refactor: remove tjaf dependency; add local TJA parser
This commit is contained in:
90
tjaf.py
Normal file
90
tjaf.py
Normal file
@@ -0,0 +1,90 @@
|
||||
import os
|
||||
import re
|
||||
from typing import Dict, Optional
|
||||
|
||||
class Tja:
|
||||
def __init__(self, text: str):
|
||||
self.text = text
|
||||
self.title: Optional[str] = None
|
||||
self.subtitle: Optional[str] = None
|
||||
self.wave: Optional[str] = None
|
||||
self.offset: Optional[float] = None
|
||||
self.courses: Dict[str, Dict[str, Optional[int]]] = {}
|
||||
self._parse()
|
||||
|
||||
def _parse(self) -> None:
|
||||
lines = self.text.split("\n")
|
||||
current_course: Optional[str] = None
|
||||
for raw in lines:
|
||||
line = raw.strip()
|
||||
if not line:
|
||||
continue
|
||||
if ":" in line:
|
||||
k, v = line.split(":", 1)
|
||||
key = k.strip().upper()
|
||||
val = v.strip()
|
||||
if key == "TITLE":
|
||||
self.title = val or None
|
||||
elif key == "SUBTITLE":
|
||||
self.subtitle = val or None
|
||||
elif key == "WAVE":
|
||||
self.wave = val or None
|
||||
elif key == "OFFSET":
|
||||
try:
|
||||
self.offset = float(val)
|
||||
except ValueError:
|
||||
self.offset = None
|
||||
elif key == "COURSE":
|
||||
course_map = {
|
||||
"EASY": "easy",
|
||||
"NORMAL": "normal",
|
||||
"HARD": "hard",
|
||||
"ONI": "oni",
|
||||
"EDIT": "ura",
|
||||
"URA": "ura",
|
||||
}
|
||||
current_course = course_map.get(val.strip().upper())
|
||||
if current_course and current_course not in self.courses:
|
||||
self.courses[current_course] = {"stars": None, "branch": False}
|
||||
elif key == "LEVEL" and current_course:
|
||||
try:
|
||||
stars = int(re.split(r"\s+", val)[0])
|
||||
except ValueError:
|
||||
stars = None
|
||||
self.courses[current_course]["stars"] = stars
|
||||
else:
|
||||
if current_course and (line.startswith("BRANCHSTART") or line.startswith("#BRANCHSTART")):
|
||||
self.courses[current_course]["branch"] = True
|
||||
|
||||
def to_mongo(self, song_id: str, created_ns: int) -> Dict:
|
||||
ext = None
|
||||
if self.wave:
|
||||
base = os.path.basename(self.wave)
|
||||
_, e = os.path.splitext(base)
|
||||
if e:
|
||||
ext = e.lstrip(".").lower()
|
||||
if not ext:
|
||||
ext = "mp3"
|
||||
courses_out: Dict[str, Optional[Dict[str, Optional[int]]]] = {}
|
||||
for name in ["easy", "normal", "hard", "oni", "ura"]:
|
||||
courses_out[name] = self.courses.get(name) or None
|
||||
return {
|
||||
"id": song_id,
|
||||
"type": "tja",
|
||||
"title": self.title,
|
||||
"subtitle": self.subtitle,
|
||||
"title_lang": {"ja": self.title, "en": None, "cn": None, "tw": None, "ko": None},
|
||||
"subtitle_lang": {"ja": self.subtitle, "en": None, "cn": None, "tw": None, "ko": None},
|
||||
"courses": courses_out,
|
||||
"enabled": False,
|
||||
"category_id": None,
|
||||
"music_type": ext,
|
||||
"offset": self.offset or 0,
|
||||
"skin_id": None,
|
||||
"preview": 0,
|
||||
"volume": 1.0,
|
||||
"maker_id": None,
|
||||
"hash": None,
|
||||
"order": song_id,
|
||||
"created_ns": created_ns,
|
||||
}
|
||||
Reference in New Issue
Block a user