mirror of
https://github.com/aclist/dztui.git
synced 2026-08-25 17:32:36 +02:00
fix: less brittle meta parsing
This commit is contained in:
parent
450d54d7fd
commit
5a8d85ac92
@ -1,6 +1,6 @@
|
||||
import hashlib
|
||||
import logging
|
||||
import shlex
|
||||
import re
|
||||
|
||||
from concurrent.futures import wait
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
@ -53,39 +53,25 @@ def is_mission(path: Path) -> bool:
|
||||
file = path / "init.c"
|
||||
return file.exists()
|
||||
|
||||
def parse_meta(file: Path) -> ModMeta | None:
|
||||
mod = file / "meta.cpp"
|
||||
if mod.exists() is False:
|
||||
return None
|
||||
def tokenize(file: str) -> dict[Any] | None:
|
||||
delimiter=r"\s*=\s*"
|
||||
modmeta = {}
|
||||
try:
|
||||
with open(file / "meta.cpp", "r") as f:
|
||||
st = f.read()
|
||||
lex = shlex.shlex(st)
|
||||
lex.whitespace += "=;"
|
||||
v = []
|
||||
while True:
|
||||
tok = lex.get_token()
|
||||
if not tok:
|
||||
break
|
||||
if tok == "protocol" or tok == "publishedid":
|
||||
ntok = lex.get_token()
|
||||
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)
|
||||
with open(file, "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
line = line.strip().rstrip(";")
|
||||
if not line:
|
||||
continue
|
||||
els = re.split(delimiter, line, maxsplit=1)
|
||||
if len(els) == 2:
|
||||
key, value = els
|
||||
print(value)
|
||||
modmeta[key.strip()] = value.strip('"')
|
||||
return modmeta
|
||||
except Exception as e:
|
||||
logger.critical(e)
|
||||
return None
|
||||
|
||||
|
||||
def get_mod_size(path: Path) -> float:
|
||||
s = 0
|
||||
for f in path.rglob("*"):
|
||||
@ -105,12 +91,12 @@ def parse_mods(mods: list[Path]) -> list[Any]:
|
||||
for mod in mods:
|
||||
mod_dir = mod.name
|
||||
symlink = _hash(mod_dir)
|
||||
meta = parse_meta(mod)
|
||||
meta = tokenize(mod)
|
||||
if meta is None:
|
||||
continue
|
||||
size = get_mod_size(mod)
|
||||
# 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())
|
||||
return clean
|
||||
|
||||
|
||||
5
tests/fixtures/cpp/meta1.cpp
vendored
Normal file
5
tests/fixtures/cpp/meta1.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
protocol = 1;
|
||||
publishedid = 1234567890;
|
||||
name = "ModName";
|
||||
timestamp = 638278452000000000;
|
||||
hash = "a1b2c3d4e5f6g7h8i9j0";
|
||||
5
tests/fixtures/cpp/meta2.cpp
vendored
Normal file
5
tests/fixtures/cpp/meta2.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
protocol = 1
|
||||
publishedid = 1234567890
|
||||
name = "ModName"
|
||||
timestamp = 638278452000000000
|
||||
hash = "a1b2c3d4e5f6g7h8i9j0"
|
||||
5
tests/fixtures/cpp/meta3.cpp
vendored
Normal file
5
tests/fixtures/cpp/meta3.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
protocol=1
|
||||
publishedid=1234567890
|
||||
name="ModName"
|
||||
timestamp=638278452000000000
|
||||
hash="a1b2c3d4e5f6g7h8i9j0"
|
||||
5
tests/fixtures/cpp/meta4.cpp
vendored
Normal file
5
tests/fixtures/cpp/meta4.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
protocol=1
|
||||
publishedid=1234567890
|
||||
name=ModName
|
||||
timestamp=638278452000000000
|
||||
hash=a1b2c3d4e5f6g7h8i9j0
|
||||
5
tests/fixtures/cpp/meta5.cpp
vendored
Normal file
5
tests/fixtures/cpp/meta5.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
protocol=1;
|
||||
publishedid=1234567890;
|
||||
name=ModName;
|
||||
timestamp=638278452000000000;
|
||||
hash=a1b2c3d4e5f6g7h8i9j0;
|
||||
5
tests/fixtures/cpp/meta6.cpp
vendored
Normal file
5
tests/fixtures/cpp/meta6.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
protocol=1
|
||||
publishedid=1234567890;
|
||||
name="ModName";
|
||||
timestamp=638278452000000000;
|
||||
hash= a1b2c3d4e5f6g7h8i9j0;
|
||||
3
tests/fixtures/cpp/test.py
vendored
Normal file
3
tests/fixtures/cpp/test.py
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
from dzgui.api.mods import tokenize
|
||||
|
||||
print(tokenize("meta4.cpp"))
|
||||
17
tests/test_modmeta.py
Normal file
17
tests/test_modmeta.py
Normal 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"
|
||||
Loading…
Reference in New Issue
Block a user