mirror of
https://github.com/rommapp/romm.git
synced 2026-04-23 06:54:40 +00:00
99 lines
2.3 KiB
Python
99 lines
2.3 KiB
Python
import re
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
from .types import LAUNCHBOX_LOCAL_DIR
|
|
|
|
|
|
def sanitize_filename(stem: str) -> str:
|
|
s = (stem or "").strip()
|
|
s = s.replace("\u2019", "'")
|
|
s = re.sub(r"[:']", "_", s)
|
|
s = re.sub(r"[\\/|<>\"?*]", "_", s)
|
|
s = re.sub(r"\s+", " ", s)
|
|
s = re.sub(r"_+", "_", s)
|
|
return s.strip(" .")
|
|
|
|
|
|
def file_uri_for_local_path(path: Path) -> str | None:
|
|
try:
|
|
relative = path.resolve().relative_to(LAUNCHBOX_LOCAL_DIR.resolve())
|
|
except ValueError:
|
|
return None
|
|
return f"file://{relative.as_posix()}"
|
|
|
|
|
|
def coalesce(*values: object | None) -> str | None:
|
|
for v in values:
|
|
if v is None:
|
|
continue
|
|
s = str(v).strip()
|
|
if s:
|
|
return s
|
|
return None
|
|
|
|
|
|
def parse_list(value: str | None) -> list[str]:
|
|
if not value:
|
|
return []
|
|
parts = re.split(r"[;,]", value)
|
|
return [p.strip() for p in parts if p and p.strip()]
|
|
|
|
|
|
def dedupe_words(values: list[str | None]) -> list[str]:
|
|
seen = {}
|
|
out: list[str] = []
|
|
|
|
for v in values:
|
|
if v is None or not v.strip():
|
|
continue
|
|
|
|
v = v.strip()
|
|
key = v.lower()
|
|
if key not in seen:
|
|
seen[key] = len(out)
|
|
out.append(v)
|
|
else:
|
|
idx = seen[key]
|
|
if out[idx].islower() and not v.islower():
|
|
out[idx] = v
|
|
return out
|
|
|
|
|
|
def parse_release_date(value: str | None) -> int | None:
|
|
if not value:
|
|
return None
|
|
|
|
try:
|
|
iso = value.replace("Z", "+00:00")
|
|
return int(datetime.fromisoformat(iso).timestamp())
|
|
except ValueError:
|
|
pass
|
|
|
|
for fmt in ("%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%d"):
|
|
try:
|
|
return int(datetime.strptime(value, fmt).timestamp())
|
|
except ValueError:
|
|
continue
|
|
|
|
return None
|
|
|
|
|
|
def parse_playmode(play_mode: str | None) -> bool:
|
|
if not play_mode:
|
|
return False
|
|
pm = play_mode.lower()
|
|
return bool(re.search(r"\b(cooperative|coop|co-op)\b", pm))
|
|
|
|
|
|
def parse_videourl(url: str | None) -> str:
|
|
if not url:
|
|
return ""
|
|
|
|
if "youtube.com/watch?v=" in url:
|
|
return url.split("v=")[-1].split("&")[0]
|
|
elif "youtu.be/" in url:
|
|
return url.split("/")[-1].split("?")[0]
|
|
|
|
return ""
|