Files
homelab-docs/homelab/scripts/resolve_steam_appid.py
2026-02-23 16:47:17 +03:00

116 lines
3.7 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.
#!/usr/bin/env python3
"""
По имени папки (игры) возвращает Steam App ID из локального steam_library_with_sizes.json.
Совпадение по нормализованному имени (регистр, пунктуация не учитываются).
Использование: resolve_steam_appid.py [PATH_TO_JSON] "Имя папки"
Выход: один appid или пусто при ненайденном.
"""
import json
import re
import sys
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
DEFAULT_JSON = SCRIPT_DIR / "steam_library_with_sizes.json"
# Ручное сопоставление: имя папки на диске -> appId (если нет в JSON или совпадение неверное)
MANUAL_MAP = {
"CM3": "351920", # Crazy Machines 3
"Darksiders 3": "606280", # Darksiders III
"DOOMEternal": "782330", # DOOM Eternal (папка без пробела)
"FarCry5": "552520", # Far Cry 5
"Gears5": "1097840", # Gears 5
"GodOfWar": "1593500", # God of War
"HITMAN 3": "1659040", # HITMAN World of Assassination
"ItTakesTwo": "1426210", # It Takes Two
"hotline_miami": "219150", # Hotline Miami
"Jaded": "1932570", # Jaded
}
def normalize(name: str) -> str:
s = (name or "").lower().strip()
s = re.sub(r"[^\w\s]", " ", s)
s = re.sub(r"\s+", " ", s)
return s.strip()
def load_library(path: Path) -> list[dict]:
with open(path, encoding="utf-8") as f:
return json.load(f)
def find_best_appid(query: str, library: list[dict]) -> str:
if not query:
return ""
qnorm = normalize(query)
if not qnorm:
return ""
qwords = set(qnorm.split())
best_appid = ""
best_score = -1
for entry in library:
name = entry.get("name") or ""
appid = entry.get("appid")
if appid is None:
continue
nnorm = normalize(name)
if not nnorm:
continue
# Точное совпадение
if nnorm == qnorm:
return str(appid)
# Оба содержат друг друга
if qnorm in nnorm or nnorm in qnorm:
score = len(qwords & set(nnorm.split()))
if score > best_score:
best_score = score
best_appid = str(appid)
# Пересечение по словам
nwords = set(nnorm.split())
overlap = len(qwords & nwords)
if overlap > 0 and overlap >= min(2, len(qwords), len(nwords)):
if overlap > best_score:
best_score = overlap
best_appid = str(appid)
return best_appid
def main() -> int:
args = [a for a in sys.argv[1:] if a.strip()]
if not args:
print("", end="")
return 0
# Путь к JSON: первый аргумент, если это путь к существующему файлу
json_path = Path(args[0])
if json_path.exists() and json_path.is_file():
path = json_path
name = " ".join(args[1:]).strip()
else:
path = DEFAULT_JSON
name = " ".join(args).strip()
if not name:
print("", end="")
return 0
if not path.exists():
sys.stderr.write(f"resolve_steam_appid: file not found: {path}\n")
print("", end="")
return 1
if name in MANUAL_MAP:
print(MANUAL_MAP[name], end="")
return 0
try:
library = load_library(path)
except Exception as e:
sys.stderr.write(f"resolve_steam_appid: {e}\n")
print("", end="")
return 1
appid = find_best_appid(name, library)
print(appid, end="")
return 0
if __name__ == "__main__":
sys.exit(main())