Files
MoviePilot/app/foundation/version.py
2026-08-14 15:45:38 +08:00

70 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import re
from typing import Optional, Tuple
_VERSION_LABELS = {"stable": -1, "rc": -2, "beta": -3, "alpha": -4}
_UNKNOWN_VERSION_LABEL = -5
_COMPARISON_TYPES = {"ge", "gt", "le", "lt", "eq", "==", ">=", ">", "<=", "<"}
def _normalize_version(version: str) -> list[int]:
"""将历史版本格式转换为保持原有排序语义的整数序列。"""
parts = re.split(r"[.-]", version.strip().lstrip("vV"))
return [
int(part)
if part.isdigit()
else _VERSION_LABELS.get(part, _UNKNOWN_VERSION_LABEL)
for part in parts
]
def compare_version(
source: str,
comparison: str,
target: str,
verbose: bool = False,
) -> Optional[bool] | Tuple[Optional[bool], str | Exception]:
"""按 MoviePilot 历史规则比较版本号,并可返回可读比较结果。"""
try:
if not source or not target:
raise ValueError("要比较的版本号不全")
if not comparison:
raise ValueError("缺少比对模式,无法比对")
if comparison not in _COMPARISON_TYPES:
raise ValueError(f"设置的版本比对模式 {comparison} 不是有效的模式!")
source_parts = _normalize_version(source)
target_parts = _normalize_version(target)
max_length = max(len(source_parts), len(target_parts))
source_parts += [0] * (max_length - len(source_parts))
target_parts += [0] * (max_length - len(target_parts))
relation = "等于"
for source_value, target_value in zip(source_parts, target_parts):
if source_value > target_value:
relation = "大于"
break
if source_value < target_value:
relation = "小于"
break
matched = {
"eq": relation == "等于",
"==": relation == "等于",
"ge": relation in {"大于", "等于"},
">=": relation in {"大于", "等于"},
"gt": relation == "大于",
">": relation == "大于",
"le": relation in {"小于", "等于"},
"<=": relation in {"小于", "等于"},
"lt": relation == "小于",
"<": relation == "小于",
}[comparison]
display_relation = (
"不等于" if comparison in {"eq", "=="} and not matched else relation
)
message = f"版本号 {source} {display_relation} 目标版本号 {target} "
return (matched, message) if verbose else matched
except Exception as err:
return (None, err) if verbose else None