|
1 | 1 | import os |
2 | | -import json |
3 | | -from pathlib import Path |
4 | 2 | import subprocess |
5 | 3 | import typing as t |
6 | 4 |
|
|
12 | 10 | from assets import res |
13 | 11 | from variables import PYPI_SOURCE |
14 | 12 | from deploy.update import Proj |
15 | | -from utils import conf, ori_path, env, uv_exc, exc_p, TaskObj, TasksObj |
| 13 | +from utils import conf, env, uv_exc, exc_p, TaskObj, TasksObj |
16 | 14 | from utils.processed_class import PreviewHtml |
17 | 15 | from utils.sql import SqlRecorder |
18 | 16 | from GUI.uic.qfluent.components import ( |
@@ -176,24 +174,103 @@ def rerun(self): |
176 | 174 | QTimer.singleShot(1000, self.gui.close) |
177 | 175 |
|
178 | 176 | def to_update(self, ver): |
179 | | - # self.gui.open_url_by_browser(self.changelog_url) |
180 | | - uv_env = {key: os.environ[key] for key in ('UV_TOOL_DIR', 'UV_TOOL_BIN_DIR') if key in os.environ} |
181 | | - tool_dir = Path(uv_env['UV_TOOL_DIR']) |
182 | | - if os.name == "nt": |
183 | | - python_exc = tool_dir / "comicguispider" / "Scripts" / "python.exe" |
184 | | - else: |
185 | | - python_exc = tool_dir / "comicguispider" / "bin" / "python" |
186 | | - with ori_path.joinpath("assets/update.txt").open("r", encoding="utf-8") as f: |
187 | | - template = f.read() |
188 | | - updater_script = template.replace(r"{uv_env_dict}", json.dumps(uv_env, ensure_ascii=False)) |
189 | | - script_path = tool_dir.joinpath("cgs_update.py") |
190 | | - with open(script_path, "w", encoding="utf-8") as f: |
191 | | - f.write(updater_script) |
192 | | - args = [str(python_exc), str(script_path), |
193 | | - '--uv-exc', uv_exc, '--version', ver, |
194 | | - '--index-url', PYPI_SOURCE[conf.pypi_source]] |
195 | | - if os.name == "nt": |
196 | | - subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_CONSOLE, env=env) |
197 | | - else: |
198 | | - subprocess.Popen(args, start_new_session=True, env=env) |
| 177 | + _UpdateLauncher(ver).run() |
199 | 178 | self.gui.close() |
| 179 | + |
| 180 | + |
| 181 | +class _UpdateLauncher: |
| 182 | + def __init__(self, ver: str): |
| 183 | + self.ver = ver |
| 184 | + self.install_spec = f"ComicGUISpider=={ver}" |
| 185 | + self.index_url = PYPI_SOURCE[conf.pypi_source] |
| 186 | + self.log_path = exc_p / "cgs_update.log" |
| 187 | + self.installer_exe = exc_p / "runtime" / "installer.exe" |
| 188 | + |
| 189 | + def run(self): |
| 190 | + if os.name == "nt" and self.installer_exe.exists(): |
| 191 | + self._run_installer() |
| 192 | + return |
| 193 | + if os.name == "nt": |
| 194 | + self._run_windows_fallback() |
| 195 | + return |
| 196 | + self._run_posix_fallback() |
| 197 | + |
| 198 | + def _run_installer(self): |
| 199 | + args = [ |
| 200 | + str(self.installer_exe), |
| 201 | + "--version", self.ver, |
| 202 | + "--uv-exc", uv_exc, |
| 203 | + "--index-url", self.index_url, |
| 204 | + "--parent-pid", str(os.getpid()), |
| 205 | + ] |
| 206 | + for key in ("UV_TOOL_DIR", "UV_TOOL_BIN_DIR"): |
| 207 | + value = os.environ.get(key) |
| 208 | + if value: |
| 209 | + args.extend([f"--{key.lower().replace('_', '-')}", value]) |
| 210 | + subprocess.Popen(args, creationflags=subprocess.CREATE_NEW_CONSOLE, env=env) |
| 211 | + |
| 212 | + def _run_windows_fallback(self): |
| 213 | + ps1_path = exc_p / "updater.ps1" |
| 214 | + script = r"""param( |
| 215 | + [Parameter(Mandatory = $true)][string]$UvExe, |
| 216 | + [Parameter(Mandatory = $true)][string]$InstallSpec, |
| 217 | + [Parameter(Mandatory = $true)][string]$IndexUrl, |
| 218 | + [Parameter(Mandatory = $true)][string]$LogPath, |
| 219 | + [string]$UvToolDir = "", |
| 220 | + [string]$UvToolBinDir = "" |
| 221 | +) |
| 222 | +
|
| 223 | +if ($UvToolDir) { $env:UV_TOOL_DIR = $UvToolDir } |
| 224 | +if ($UvToolBinDir) { $env:UV_TOOL_BIN_DIR = $UvToolBinDir } |
| 225 | +
|
| 226 | +& $UvExe tool install $InstallSpec --force --index-url $IndexUrl 2>&1 | |
| 227 | + Tee-Object -FilePath $LogPath |
| 228 | +
|
| 229 | +if ($LASTEXITCODE -ne 0) { |
| 230 | + Write-Host "`nUpdate failed (exit code: $LASTEXITCODE)" -ForegroundColor Red |
| 231 | +} |
| 232 | +
|
| 233 | +Read-Host "Press Enter to close" |
| 234 | +""" |
| 235 | + self._write(ps1_path, script) |
| 236 | + subprocess.Popen( |
| 237 | + [ |
| 238 | + "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-NoExit", |
| 239 | + "-File", str(ps1_path), |
| 240 | + "-UvExe", uv_exc, |
| 241 | + "-InstallSpec", self.install_spec, |
| 242 | + "-IndexUrl", self.index_url, |
| 243 | + "-LogPath", str(self.log_path), |
| 244 | + "-UvToolDir", os.environ.get("UV_TOOL_DIR", ""), |
| 245 | + "-UvToolBinDir", os.environ.get("UV_TOOL_BIN_DIR", ""), |
| 246 | + ], |
| 247 | + creationflags=subprocess.CREATE_NEW_CONSOLE, |
| 248 | + env=env, |
| 249 | + ) |
| 250 | + |
| 251 | + def _run_posix_fallback(self): |
| 252 | + sh_path = exc_p / "updater.sh" |
| 253 | + script = """#!/bin/sh |
| 254 | +uv_exe="$1" |
| 255 | +install_spec="$2" |
| 256 | +index_url="$3" |
| 257 | +log_path="$4" |
| 258 | +
|
| 259 | +"$uv_exe" tool install "$install_spec" --force --index-url "$index_url" 2>&1 | tee -a "$log_path" |
| 260 | +echo "done" |
| 261 | +printf "Press any key to close..." |
| 262 | +stty -icanon -echo |
| 263 | +dd bs=1 count=1 >/dev/null 2>&1 |
| 264 | +stty icanon echo |
| 265 | +""" |
| 266 | + self._write(sh_path, script) |
| 267 | + os.chmod(sh_path, 0o755) |
| 268 | + subprocess.Popen( |
| 269 | + ["setsid", "sh", str(sh_path), uv_exc, self.install_spec, self.index_url, str(self.log_path)], |
| 270 | + start_new_session=True, |
| 271 | + env=env, |
| 272 | + ) |
| 273 | + |
| 274 | + @staticmethod |
| 275 | + def _write(path, content: str): |
| 276 | + path.write_text(content, encoding="utf-8") |
0 commit comments