mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-15 11:04:12 +08:00
70 lines
2.5 KiB
Python
70 lines
2.5 KiB
Python
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
|