Initial commit

This commit is contained in:
Maxim
2025-12-16 22:16:45 +03:00
commit bf03750e76
64 changed files with 7619 additions and 0 deletions

View File

@@ -0,0 +1 @@
"" # Package marker

View File

@@ -0,0 +1 @@
"" # Package marker

View File

@@ -0,0 +1,104 @@
import re
import sys
from pathlib import Path
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from api.models import Aspect, Hero, Item
# Add data directory to path for imports
sys.path.insert(0, str(Path(settings.BASE_DIR) / "data"))
from facets import HERO_FACETS
def _strip_comments(text: str) -> str:
"""Remove single-line and block comments from TypeScript data."""
text = re.sub(r"/\*.*?\*/", "", text, flags=re.S)
lines = []
for line in text.splitlines():
stripped = line.strip()
if stripped.startswith("//"):
continue
lines.append(line)
return "\n".join(lines)
def _extract_objects(text: str, require_primary: bool = False):
cleaned = _strip_comments(text)
objects = []
for match in re.finditer(r"\{[^}]*\}", cleaned):
chunk = match.group(0)
entry = {}
id_match = re.search(r"['\"]?id['\"]?\s*:\s*(['\"])(.*?)\1", chunk)
name_match = re.search(r"['\"]?name['\"]?\s*:\s*(['\"])(.*?)\1", chunk)
if not (id_match and name_match):
continue
entry["slug"] = id_match.group(2)
entry["name"] = name_match.group(2)
if require_primary:
primary_match = re.search(r"['\"]?primary['\"]?\s*:\s*(['\"])(.*?)\1", chunk)
if not primary_match:
continue
entry["primary"] = primary_match.group(2)
if len(entry) == (3 if require_primary else 2):
objects.append(entry)
return objects
class Command(BaseCommand):
help = "Load heroes, items and facets from data files into the database."
def handle(self, *args, **options):
base_dir = Path(settings.BASE_DIR)
heroes_path = base_dir / "data" / "heroes.ts"
items_path = base_dir / "data" / "items.ts"
if not heroes_path.exists() or not items_path.exists():
raise CommandError("Missing data files in the ./data directory.")
heroes = _extract_objects(heroes_path.read_text(encoding="utf-8"), require_primary=True)
items = _extract_objects(items_path.read_text(encoding="utf-8"), require_primary=False)
if not heroes:
raise CommandError("Failed to parse heroes.ts")
if not items:
raise CommandError("Failed to parse items.ts")
hero_created = item_created = aspect_created = 0
for hero in heroes:
hero_obj, created = Hero.objects.update_or_create(
name=hero["name"],
defaults={
"primary": hero["primary"],
},
)
hero_created += int(created)
# Load facets for this hero
facets = HERO_FACETS.get(hero["name"], [])
for facet_name in facets:
_, facet_created = Aspect.objects.update_or_create(
hero=hero_obj,
name=facet_name,
)
aspect_created += int(facet_created)
for item in items:
_, created = Item.objects.update_or_create(
name=item["name"],
)
item_created += int(created)
self.stdout.write(
self.style.SUCCESS(
f"Loaded {len(heroes)} heroes ({hero_created} new), "
f"{len(items)} items ({item_created} new), "
f"and {aspect_created} new facets."
)
)