fix: less brittle meta parsing

This commit is contained in:
aclist committed 2026-06-11 15:11:38 +09:00
1 parent 450d54d7fd
commit 5a8d85ac92
9 files changed
+67 -31

No files matched your search

+17 -31
View File
@@ -1,6 +1,6 @@
import hashlib import hashlib
import logging import logging
import shlex import re
from concurrent.futures import wait from concurrent.futures import wait
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
@@ -53,39 +53,25 @@ def is_mission(path: Path) -> bool:
file = path / "init.c" file = path / "init.c"
return file.exists() return file.exists()
def parse_meta(file: Path) -> ModMeta | None: def tokenize(file: str) -> dict[Any] | None:
mod = file / "meta.cpp" delimiter=r"\s*=\s*"
if mod.exists() is False: modmeta = {}
return None
try: try:
with open(file / "meta.cpp", "r") as f: with open(file, "r", encoding="utf-8") as file:
st = f.read() for line in file:
lex = shlex.shlex(st) line = line.strip().rstrip(";")
lex.whitespace += "=;" if not line:
v = [] continue
while True: els = re.split(delimiter, line, maxsplit=1)
tok = lex.get_token() if len(els) == 2:
if not tok: key, value = els
break print(value)
if tok == "protocol" or tok == "publishedid": modmeta[key.strip()] = value.strip('"')
ntok = lex.get_token() return modmeta
elif tok == "timestamp":
# NOTE: some malformed .NET tick conversions result in numbers < 0
ntok = lex.get_token()
if ntok == "-":
ntok += str(lex.get_token())
elif tok == "name":
ntok = lex.get_token()
if ntok is not None:
ntok = ntok.split('"')[1]
if ntok is not None:
v.append(ntok)
return ModMeta(*v)
except Exception as e: except Exception as e:
logger.critical(e) logger.critical(e)
return None return None
def get_mod_size(path: Path) -> float: def get_mod_size(path: Path) -> float:
s = 0 s = 0
for f in path.rglob("*"): for f in path.rglob("*"):
@@ -105,12 +91,12 @@ def parse_mods(mods: list[Path]) -> list[Any]:
for mod in mods: for mod in mods:
mod_dir = mod.name mod_dir = mod.name
symlink = _hash(mod_dir) symlink = _hash(mod_dir)
meta = parse_meta(mod) meta = tokenize(mod)
if meta is None: if meta is None:
continue continue
size = get_mod_size(mod) size = get_mod_size(mod)
# NOTE: final col is cell renderer highlight toggle # NOTE: final col is cell renderer highlight toggle
clean.append([meta.name, symlink, mod_dir, size, False]) clean.append([meta["name"], symlink, mod_dir, size, False])
clean.sort(key=lambda row: str(row[0]).casefold()) clean.sort(key=lambda row: str(row[0]).casefold())
return clean return clean
+5
View File
@@ -0,0 +1,5 @@
protocol = 1;
publishedid = 1234567890;
name = "ModName";
timestamp = 638278452000000000;
hash = "a1b2c3d4e5f6g7h8i9j0";
+5
View File
@@ -0,0 +1,5 @@
protocol = 1
publishedid = 1234567890
name = "ModName"
timestamp = 638278452000000000
hash = "a1b2c3d4e5f6g7h8i9j0"
+5
View File
@@ -0,0 +1,5 @@
protocol=1
publishedid=1234567890
name="ModName"
timestamp=638278452000000000
hash="a1b2c3d4e5f6g7h8i9j0"
+5
View File
@@ -0,0 +1,5 @@
protocol=1
publishedid=1234567890
name=ModName
timestamp=638278452000000000
hash=a1b2c3d4e5f6g7h8i9j0
+5
View File
@@ -0,0 +1,5 @@
protocol=1;
publishedid=1234567890;
name=ModName;
timestamp=638278452000000000;
hash=a1b2c3d4e5f6g7h8i9j0;
+5
View File
@@ -0,0 +1,5 @@
protocol=1
publishedid=1234567890;
name="ModName";
timestamp=638278452000000000;
hash= a1b2c3d4e5f6g7h8i9j0;
+3
View File
@@ -0,0 +1,3 @@
from dzgui.api.mods import tokenize
print(tokenize("meta4.cpp"))
+17
View File
@@ -0,0 +1,17 @@
import pytest
from dzgui.api.mods import tokenize
from tests.fixtures import fixture_path
@pytest.mark.mods
@pytest.mark.parametrize("fixture", [
fixture_path("cpp/meta1.cpp"),
fixture_path("cpp/meta2.cpp"),
fixture_path("cpp/meta3.cpp"),
fixture_path("cpp/meta4.cpp"),
fixture_path("cpp/meta5.cpp"),
fixture_path("cpp/meta6.cpp"),
]
)
def test_modmeta(fixture: str) -> None:
meta = tokenize(fixture)
assert meta["name"] == "ModName"