feat: 完善数据库备份管理与版本读取 (#6450)

This commit is contained in:
InfinityPacer
2026-08-25 16:05:45 +08:00
committed by GitHub
parent b952a3e407
commit d58c8d2b17
38 changed files with 1846 additions and 459 deletions
+15 -3
View File
@@ -8,13 +8,16 @@ import tempfile
from datetime import datetime
from pathlib import Path
from app.runtime.version import get_app_version
_BACKUP_NAME = re.compile(
r"^(?P<db_type>sqlite|postgresql)_"
r"^(?:moviepilot_(?P<version>v\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)_)?"
r"(?P<db_type>sqlite|postgresql)_"
r"(?P<timestamp>\d{8}_\d{6})"
r"(?:_(?P<sequence>\d+))?"
r"(?P<suffix>\.db|\.dump)$"
)
_RELEASE_VERSION = re.compile(r"^v\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$")
class BackupFiles:
@@ -68,10 +71,19 @@ class BackupFiles:
"""删除一个已通过名称约束的备份文件。"""
self.resolve(name).unlink()
def available_name(self, *, db_type: str, created_at: datetime, suffix: str) -> str:
def available_name(
self,
*,
db_type: str,
created_at: datetime,
suffix: str,
) -> str:
"""生成包含数据库类型和秒级时间的简短可读文件名。"""
timestamp = created_at.strftime("%Y%m%d_%H%M%S")
base = f"{db_type}_{timestamp}"
version = get_app_version().strip()
if _RELEASE_VERSION.fullmatch(version) is None:
raise ValueError("程序版本号无法用于数据库备份命名")
base = f"moviepilot_{version}_{db_type}_{timestamp}"
candidate = f"{base}{suffix}"
sequence = 1
while (self.root / candidate).exists():
+2 -2
View File
@@ -26,7 +26,7 @@ import psutil
from app.schemas.dashboard import DashboardMemoryInfo as _SchemaDashboardMemoryInfo
from app.schemas.dashboard import DashboardSystemInfo as _SchemaDashboardSystemInfo
from app.schemas.dashboard import ProcessInfo as _SchemaProcessInfo
from version import APP_VERSION
from app.runtime.version import get_app_version
from app.foundation.environment import (
is_aarch,
is_aarch64,
@@ -948,7 +948,7 @@ class SystemUtils:
hostname=socket.gethostname(),
operating_system=SystemUtils._operating_system_name(),
runtime=max(0, int(time.time() - psutil.Process().create_time())),
version=APP_VERSION,
version=get_app_version(),
)
@staticmethod
+10 -6
View File
@@ -16,12 +16,12 @@ from typing import Any, Optional
from app.adapters.network.http import RequestUtils
from app.foundation.singleton import SingletonClass
from app.foundation.version import compare_version
from app.runtime.version import get_app_version
from app.foundation.environment import is_docker
from app.runtime.log import logger
from app.runtime.settings import get_runtime_setting
from app.runtime.thread import ThreadHelper
from app.schemas.system import SystemUpdateStatus
from version import APP_VERSION
class SystemUpdateManager(metaclass=SingletonClass):
@@ -66,13 +66,17 @@ class SystemUpdateManager(metaclass=SingletonClass):
return datetime.now(timezone.utc).isoformat()
def _default_state(self) -> dict[str, Any]:
return SystemUpdateStatus(current_version=APP_VERSION).model_dump()
return SystemUpdateStatus(current_version=get_app_version()).model_dump()
def _read_state(self) -> dict[str, Any]:
try:
payload = json.loads(self._state_file.read_text(encoding="utf-8"))
if isinstance(payload, dict):
return {**self._default_state(), **payload, "current_version": APP_VERSION}
return {
**self._default_state(),
**payload,
"current_version": get_app_version(),
}
except (OSError, json.JSONDecodeError):
pass
return self._default_state()
@@ -81,7 +85,7 @@ class SystemUpdateManager(metaclass=SingletonClass):
with self._lock:
state = self._read_state()
state.update(changes)
state["current_version"] = APP_VERSION
state["current_version"] = get_app_version()
state["progress"] = self._progress(
state.get("downloaded_bytes", 0), state.get("total_bytes", 0)
)
@@ -117,7 +121,7 @@ class SystemUpdateManager(metaclass=SingletonClass):
can_update=True,
can_install=False,
)
if state.get("state") == "installing" and target == APP_VERSION:
if state.get("state") == "installing" and target == get_app_version():
self._install_file.unlink(missing_ok=True)
state = self._write_state(
state="idle",
@@ -161,7 +165,7 @@ class SystemUpdateManager(metaclass=SingletonClass):
if not release:
raise RuntimeError("未找到可用的 v3 稳定版本")
version = str(release["tag_name"])
has_update = compare_version(version, "gt", APP_VERSION) is True
has_update = compare_version(version, "gt", get_app_version()) is True
return SystemUpdateStatus.model_validate(
self._write_state(
state="available" if has_update else "idle",