Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,3 @@ config/backups/
/docs/rust-feasibility/assessment-startup.json
/docs/rust-feasibility/assessment-size.json
/startup.json

# 源码应用的运行时安装目录
/third_party/
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,3 @@
[submodule "updater"]
path = updater
url = https://github.com/LevelDownRefine/updater.git
[submodule "uv-app-manager"]
path = uv-app-manager
url = https://github.com/LevelDownRefine/uv-app-manager.git
12 changes: 0 additions & 12 deletions config/source_applications.yml

This file was deleted.

2 changes: 0 additions & 2 deletions python-backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ dependencies = [
"colorama==0.4.6",
"psutil==6.1.1",
"leveldown-updater",
"source-app-manager",
"pycaw==20220416",
"pyinstaller==6.19.0",
"pywin32==311; sys_platform == 'win32'",
Expand All @@ -26,7 +25,6 @@ build-backend = "setuptools.build_meta"

[tool.uv.sources]
leveldown-updater = { path = "../updater", editable = true }
source-app-manager = { path = "../uv-app-manager", editable = true }

[tool.setuptools.packages.find]
where = ["."]
Expand Down
4 changes: 1 addition & 3 deletions python-backend/src/config/set_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from src.utils import open_in_explorer, utils_launcher
from src.utils.utils_dict import get_field
from src.utils.utils_sub_config import (
declared_relative_path,
get_script_game_path,
load_game_config,
resolve_script_path,
Expand Down Expand Up @@ -537,8 +536,7 @@ def get_game_path_keys(script_name: str, rel: str) -> tuple[str, ...]:
return ()
game = cfg.resources["game"]
assert "config" in game and "keys" in game
config_path = declared_relative_path(script_name, game["config"])
if rel.casefold() != config_path.casefold():
if rel.casefold() != game["config"].casefold():
return ()
return tuple(game["keys"])

Expand Down
10 changes: 0 additions & 10 deletions python-backend/src/headless.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ def update_script(
weekly_timeouts,
switches,
task_options=None,
source_manual_arguments_text=None,
):
from src.service.script_service import ScriptEdit

Expand All @@ -155,7 +154,6 @@ def update_script(
weekly_timeouts,
switches,
{} if task_options is None else task_options,
source_manual_arguments_text,
)
return {"script_name": self.service.update_script(edit)}

Expand Down Expand Up @@ -303,11 +301,6 @@ def rpc_methods(service, *, persistent=True) -> dict:
methods = {
"app.snapshot": service.app_snapshot,
"backup.start": service.start_backup,
"source.install": service.source_apps.start_install,
"source.catalog": service.source_apps.catalog,
"source.install_catalog": service.source_apps.start_catalog_install,
"source.register": service.source_apps.register,
"source.configure": service.source_apps.configure,
"restore.start": service.start_restore,
"job.poll": service.poll_job,
"job.cancel": service.cancel_job,
Expand Down Expand Up @@ -347,7 +340,6 @@ def rpc_methods(service, *, persistent=True) -> dict:
}
readonly = {
"app.snapshot",
"source.catalog",
"job.poll",
"update.view",
"settings.view",
Expand All @@ -366,8 +358,6 @@ def rpc_methods(service, *, persistent=True) -> dict:
}
session_only = {
"backup.start",
"source.install",
"source.install_catalog",
"restore.start",
"job.poll",
"job.cancel",
Expand Down
21 changes: 1 addition & 20 deletions python-backend/src/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@ def resolve_script_target(script_name: str, target: str) -> dict:
return _unavailable("未找到脚本路径")
resolved = resolve_script_path(script["script_path"])
if target == "folder":
path = (
resolve_script_path(script["source_root"])
if "source_root" in script
else os.path.dirname(resolved)
)
path = os.path.dirname(resolved)
else:
path = get_log_dir(script)
if path is None:
Expand Down Expand Up @@ -113,21 +109,6 @@ def resolve_launch_target(script_name: str, target: str) -> dict:
resolved = resolve_script_path(path)
if not resolved or not os.path.isfile(resolved):
return _unavailable("启动文件不存在,请检查配置")
if "source_root" in script:
from src.service.source_app_service import source_launch_command

try:
arguments = script.get("source_manual_arguments", [])
command = source_launch_command(script, arguments)
except (OSError, ValueError, RuntimeError) as exc:
return _unavailable(str(exc))
return {
"kind": "command",
"program": command.program,
"args": list(command.arguments),
"cwd": command.working_directory,
"env": {},
}
script_type = script["script_type"] if "script_type" in script else "external" # noqa: SIM401
if script_type != "python":
return {"kind": "association", "path": os.path.abspath(resolved)}
Expand Down
5 changes: 0 additions & 5 deletions python-backend/src/service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
| `schedule.py`、`run_actions.py` | 运行选项、调度、前后动作与失败重跑 |
| `daily_plan.py` | 每日计划、Windows 任务注册与状态回读 |
| `backup_service.py` | 配置 ZIP 备份与恢复 |
| `source_app_service.py` | 源码应用安装、登记及启动配置 |
| `../link.py`、`../utils/utils_wallpaper.py` | 资源/启动目标、壁纸映射与缓存 |
| `../update.py`、`../utils/utils_job.py` | 更新适配与会话、后台任务执行 |

Expand Down Expand Up @@ -42,10 +41,6 @@ Windows 任务按当前用户和安装目录标识,需管理员权限注册及

覆盖前备份目标文件,逐文件原子替换;不承诺整批事务回滚。失败结果保留完成数量和恢复前 ZIP,供用户核对。归档安全检查与路径校验归后端。

## 源码应用

`AppService.source_apps` 统一提供源码应用目录、安装、登记和配置入口;安装与更新、备份共用后台任务执行器及进度查询。应用安装在助手根目录的 `third_party/<应用标识>/`,通用源码安装与 Python 环境管理由 `uv-app-manager` 提供。

## 手动更新

更新内核独立维护于 `updater/`;`src/update.py` 负责助手适配、`UpdateSession` 和独立更新器入口,AppService 只委托。
Expand Down
10 changes: 0 additions & 10 deletions python-backend/src/service/app_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
- 游戏侧 config 适配器(副本/周几起写脚本自身 config):归 :mod:`src.config.set_config` 模块函数
- 自定义壁纸表(config/wallpaper.json):归 :mod:`src.utils.utils_wallpaper` 模块函数
- 配置备份与恢复(各子脚本 config 打包为 ZIP / 按目录原样回写):归 :mod:`src.service.backup_service` 模块函数
- 源码应用管理:归 :class:`src.service.source_app_service.SourceAppService`
- 助手手动更新(检查 / 下载 / 安装交接):归 :class:`src.update.UpdateService`

GUI(MainWindow)与 CLI(各子命令)都只实例化本类,控制器经构造注入持有它;
Expand All @@ -27,7 +26,6 @@
import src.service.chain_service as chain_service
import src.service.daily_plan as daily_plan
import src.service.script_service as script_service
import src.service.source_app_service as source_app_service
import src.service.task_service as task_service
from src.config.native_task_switch import native_task_switch_of
from src.config.set_config import (
Expand Down Expand Up @@ -105,7 +103,6 @@ def __init__(self, *, frontend: str = "qt"):
"""装配各 peer;GUI/CLI 入口选择对应发行版的更新服务。"""
self._updates = UpdateService(frontend=frontend)
self.jobs = JobExecutor()
self.source_apps = source_app_service.SourceAppService(self.jobs)
self._update_session = UpdateSession(self._updates, self.jobs)

def close(self) -> None:
Expand Down Expand Up @@ -229,13 +226,6 @@ def script_edit_view(self, script_name: str) -> dict:
script = self.get_script(script_name)
if script is None:
raise InvalidScript("脚本已不存在,请刷新列表")
if "source_root" in script:
script = {
**script,
"source_manual_arguments_text": source_app_service.format_arguments(
script["source_manual_arguments"]
),
}
return {
"script_name": script_name,
"script": script,
Expand Down
3 changes: 1 addition & 2 deletions python-backend/src/service/backup_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from src.config.set_config import get_game_path_keys, iter_backup_paths
from src.utils import get_path_under_root
from src.utils.utils_io import dump_data_str, load_data, parse_data
from src.utils.utils_sub_config import declared_relative_path, get_script_root_dir
from src.utils.utils_sub_config import get_script_root_dir

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -51,7 +51,6 @@ def create_backup() -> dict:
if root is None:
continue
for rel in paths:
rel = declared_relative_path(script_name, rel)
source = Path(root, rel)
if source.is_file():
files[
Expand Down
24 changes: 0 additions & 24 deletions python-backend/src/service/chain_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@
自 ``gui.chain`` 迁出:不依赖 Qt,收编到 service 层便于无头测试与 GUI/CLI 共用。
"""

import base64
import copy
import logging
from datetime import datetime
from pathlib import Path

from src.service.source_app_service import source_launch_command
from src.utils import (
get_path_under_root,
safe_path_join,
Expand Down Expand Up @@ -155,27 +152,6 @@ def generate_chain_config(
script["enabled"] = True
log_path = resolve_log_path(script)
script["log_path"] = str(log_path) if log_path is not None else ""
if "source_root" in script:
arguments = script.get("source_arguments", [])
command = source_launch_command(script, arguments)
script["script_type"] = "external"
# 旧 runner 以程序路径的父目录启动进程;在解释器内切换目录并
# 执行入口;编码为单个参数,避免旧 runner 拆分路径和引号。
entry, *args = command.arguments
bootstrap = (
"import os,runpy,sys\n"
f"os.chdir({command.working_directory!r})\n"
f"sys.argv={[entry, *args]!r}\n"
f"sys.path[0]={str(Path(entry).parent)!r}\n"
f"runpy.run_path({entry!r},run_name='__main__')\n"
)
encoded = base64.b64encode(bootstrap.encode("utf-8")).decode("ascii")
script["script_path"] = command.program
script["script_arguments"] = (
f"-c exec(__import__('base64').b64decode('{encoded}'))"
)
script["launcher_mode"] = False
script["script_process_name"] = []
script.pop("log_analysis_path", None)
filtered.append(script)

Expand Down
28 changes: 0 additions & 28 deletions python-backend/src/service/script_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class ScriptEdit:
weekly_timeouts: list[int | None] # weekly.yml
switches: dict[str, bool] # 脚本自身 config
task_options: dict[str, bool | str | list[str]] = field(default_factory=dict)
source_manual_arguments_text: str | None = None


class InvalidScript(ValueError):
Expand All @@ -53,10 +52,6 @@ def validate_edit(edit: ScriptEdit, *, scripts: list[dict] | None = None) -> Scr
raise InvalidScript("脚本标识不能为空")
if not isinstance(edit.display_name, str) or not edit.display_name.strip():
raise InvalidScript("脚本名称不能为空")
if edit.source_manual_arguments_text is not None and not isinstance(
edit.source_manual_arguments_text, str
):
raise InvalidScript("手动启动参数必须为文本")
patch = edit.config_patch
if not isinstance(patch, dict) or set(patch) != set(
_TEXT_FIELDS + _BOOL_FIELDS + _INT_FIELDS
Expand Down Expand Up @@ -233,29 +228,6 @@ def update(edit: ScriptEdit) -> str:
except ValueError as exc:
raise InvalidScript(str(exc)) from exc

if "source_root" in target:
from src.service.source_app_service import (
parse_arguments,
source_launch_command,
)

if edit.config_patch["script_type"] != "external":
raise InvalidScript("源码应用必须使用 external 类型")
try:
arguments = parse_arguments(edit.config_patch["script_arguments"])
candidate = {**target, **edit.config_patch}
source_launch_command(candidate, arguments)
manual = (
parse_arguments(edit.source_manual_arguments_text)
if edit.source_manual_arguments_text is not None
else target["source_manual_arguments"]
)
source_launch_command(candidate, manual)
except (OSError, ValueError, RuntimeError) as exc:
raise InvalidScript(f"源码应用无效: {exc}") from exc
target["source_arguments"] = arguments
target["source_manual_arguments"] = manual

target.update(edit.config_patch)
target["display_name"] = edit.display_name
new_script_name = get_script_name(target)
Expand Down
Loading
Loading