3
2
forked from Dniel97/artemis
artemis/titles/chuni/read.py

158 lines
7.4 KiB
Python

from typing import Optional
from os import walk, path
import xml.etree.ElementTree as ET
from read import BaseReader
from core.config import CoreConfig
from titles.chuni.database import ChuniData
from titles.chuni.const import ChuniConstants
class ChuniReader(BaseReader):
def __init__(self, config: CoreConfig, version: int, bin_dir: Optional[str], opt_dir: Optional[str], extra: Optional[str]) -> None:
super().__init__(config, version, bin_dir, opt_dir, extra)
self.data = ChuniData(config)
try:
self.logger.info(f"Start importer for {ChuniConstants.game_ver_to_string(version)}")
except IndexError:
self.logger.error(f"Invalid chunithm version {version}")
exit(1)
def read(self) -> None:
data_dirs = []
if self.bin_dir is not None:
data_dirs += self.get_data_directories(self.bin_dir)
if self.opt_dir is not None:
data_dirs += self.get_data_directories(self.opt_dir)
for dir in data_dirs:
self.logger.info(f"Read from {dir}")
self.read_events(f"{dir}/event")
self.read_music(f"{dir}/music")
self.read_charges(f"{dir}/chargeItem")
self.read_avatar(f"{dir}/avatarAccessory")
def read_events(self, evt_dir: str) -> None:
for root, dirs, files in walk(evt_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/Event.xml"):
with open(f"{root}/{dir}/Event.xml", 'rb') as fp:
bytedata = fp.read()
strdata = bytedata.decode('UTF-8')
xml_root = ET.fromstring(strdata)
for name in xml_root.findall('name'):
id = name.find('id').text
name = name.find('str').text
for substances in xml_root.findall('substances'):
event_type = substances.find('type').text
result = self.data.static.put_event(self.version, id, event_type, name)
if result is not None:
self.logger.info(f"Inserted event {id}")
else:
self.logger.warn(f"Failed to insert event {id}")
def read_music(self, music_dir: str) -> None:
for root, dirs, files in walk(music_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/Music.xml"):
with open(f"{root}/{dir}/Music.xml", 'rb') as fp:
bytedata = fp.read()
strdata = bytedata.decode('UTF-8')
xml_root = ET.fromstring(strdata)
for name in xml_root.findall('name'):
song_id = name.find('id').text
title = name.find('str').text
for artistName in xml_root.findall('artistName'):
artist = artistName.find('str').text
for genreNames in xml_root.findall('genreNames'):
for list_ in genreNames.findall('list'):
for StringID in list_.findall('StringID'):
genre = StringID.find('str').text
for jaketFile in xml_root.findall('jaketFile'): #nice typo, SEGA
jacket_path = jaketFile.find('path').text
for fumens in xml_root.findall('fumens'):
for MusicFumenData in fumens.findall('MusicFumenData'):
fumen_path = MusicFumenData.find('file').find("path")
if fumen_path.text is not None:
chart_id = MusicFumenData.find('type').find('id').text
if chart_id == "4":
level = float(xml_root.find("starDifType").text)
we_chara = xml_root.find("worldsEndTagName").find("str").text
else:
level = float(f"{MusicFumenData.find('level').text}.{MusicFumenData.find('levelDecimal').text}")
we_chara = None
result = self.data.static.put_music(
self.version,
song_id,
chart_id,
title,
artist,
level,
genre,
jacket_path,
we_chara
)
if result is not None:
self.logger.info(f"Inserted music {song_id} chart {chart_id}")
else:
self.logger.warn(f"Failed to insert music {song_id} chart {chart_id}")
def read_charges(self, charge_dir: str) -> None:
for root, dirs, files in walk(charge_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/ChargeItem.xml"):
with open(f"{root}/{dir}/ChargeItem.xml", 'rb') as fp:
bytedata = fp.read()
strdata = bytedata.decode('UTF-8')
xml_root = ET.fromstring(strdata)
for name in xml_root.findall('name'):
id = name.find('id').text
name = name.find('str').text
expirationDays = xml_root.find('expirationDays').text
consumeType = xml_root.find('consumeType').text
sellingAppeal = bool(xml_root.find('sellingAppeal').text)
result = self.data.static.put_charge(self.version, id, name, expirationDays, consumeType, sellingAppeal)
if result is not None:
self.logger.info(f"Inserted charge {id}")
else:
self.logger.warn(f"Failed to insert charge {id}")
def read_avatar(self, avatar_dir: str) -> None:
for root, dirs, files in walk(avatar_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/AvatarAccessory.xml"):
with open(f"{root}/{dir}/AvatarAccessory.xml", 'rb') as fp:
bytedata = fp.read()
strdata = bytedata.decode('UTF-8')
xml_root = ET.fromstring(strdata)
for name in xml_root.findall('name'):
id = name.find('id').text
name = name.find('str').text
category = xml_root.find('category').text
for image in xml_root.findall('image'):
iconPath = image.find('path').text
for texture in xml_root.findall('texture'):
texturePath = texture.find('path').text
result = self.data.static.put_avatar(self.version, id, name, category, iconPath, texturePath)
if result is not None:
self.logger.info(f"Inserted avatarAccessory {id}")
else:
self.logger.warn(f"Failed to insert avatarAccessory {id}")