117 lines
3.1 KiB
Python
117 lines
3.1 KiB
Python
"""应用路径:开发目录 vs PyInstaller 打包 exe。"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def is_frozen() -> bool:
|
|
return bool(getattr(sys, "frozen", False))
|
|
|
|
|
|
def app_root() -> Path:
|
|
"""exe 所在目录 / 源码目录(可写:浏览器、输出 JSON)。"""
|
|
if is_frozen():
|
|
return Path(sys.executable).resolve().parent
|
|
return Path(__file__).resolve().parent
|
|
|
|
|
|
def bundle_root() -> Path:
|
|
"""打包内资源目录(只读)。"""
|
|
if is_frozen():
|
|
return Path(getattr(sys, "_MEIPASS", app_root()))
|
|
return app_root()
|
|
|
|
|
|
def ui_html_path() -> Path:
|
|
for candidate in (
|
|
bundle_root() / "douyin_collector_ui.html",
|
|
app_root() / "douyin_collector_ui.html",
|
|
):
|
|
if candidate.is_file():
|
|
return candidate
|
|
return app_root() / "douyin_collector_ui.html"
|
|
|
|
|
|
def is_gui_mode() -> bool:
|
|
"""无黑窗口模式:pythonw / 无控制台 exe / COLLECTOR_GUI=1。"""
|
|
if os.environ.get("DOUYIN_CONSOLE") == "1":
|
|
return False
|
|
if os.environ.get("COLLECTOR_GUI") == "1":
|
|
return True
|
|
if Path(sys.executable).name.lower() == "pythonw.exe":
|
|
return True
|
|
if is_frozen() and sys.platform == "win32":
|
|
try:
|
|
import ctypes
|
|
return ctypes.windll.kernel32.GetConsoleWindow() == 0
|
|
except Exception:
|
|
return True
|
|
return False
|
|
|
|
|
|
def splash_html_path() -> Path:
|
|
for candidate in (
|
|
bundle_root() / "splash.html",
|
|
app_root() / "splash.html",
|
|
):
|
|
if candidate.is_file():
|
|
return candidate
|
|
return app_root() / "splash.html"
|
|
|
|
|
|
def launch_splash() -> None:
|
|
"""立即打开启动动画页(空白期反馈)。"""
|
|
if os.environ.get("SPLASH_LAUNCHED") == "1":
|
|
return
|
|
splash = splash_html_path()
|
|
if not splash.is_file():
|
|
return
|
|
os.environ["SPLASH_LAUNCHED"] = "1"
|
|
if sys.platform == "win32":
|
|
try:
|
|
import subprocess
|
|
subprocess.Popen(
|
|
["cmd", "/c", "start", "", str(splash.resolve())],
|
|
creationflags=getattr(subprocess, "CREATE_NO_WINDOW", 0),
|
|
close_fds=True,
|
|
)
|
|
return
|
|
except Exception:
|
|
pass
|
|
try:
|
|
import webbrowser
|
|
webbrowser.open(splash.resolve().as_uri())
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def use_incognito_ui() -> bool:
|
|
"""凭证页与登录页均在 Playwright 无痕窗口内打开(默认开启)。"""
|
|
if os.environ.get("DOUYIN_CONSOLE") == "1":
|
|
return False
|
|
if os.environ.get("COLLECTOR_EXTERNAL_BROWSER") == "1":
|
|
return False
|
|
return True
|
|
|
|
|
|
def browser_ready_file() -> Path:
|
|
return app_root() / ".browser_ready"
|
|
|
|
|
|
def clear_browser_ready() -> None:
|
|
try:
|
|
path = browser_ready_file()
|
|
if path.is_file():
|
|
path.unlink()
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def signal_browser_ready() -> None:
|
|
try:
|
|
browser_ready_file().write_text(str(int(__import__("time").time())), encoding="utf-8")
|
|
except Exception:
|
|
pass
|