skyeweave/skyeweave/service/atlas.py

138 lines
4.8 KiB
Python
Raw Normal View History

2024-10-14 20:23:09 +02:00
import logging
2024-10-18 15:59:18 +02:00
import pathlib
2025-04-05 20:02:05 +02:00
from typing import Annotated, List, Tuple, TypedDict
2024-08-09 18:57:33 +02:00
import requests
2025-04-05 20:02:05 +02:00
# Backport of NotRequired for python 3.10 and older
try:
from typing import NotRequired
except ImportError:
from typing_extensions import NotRequired
2024-10-16 22:13:39 +02:00
from ..config import AtlasAPIConfig, PathConfig, ExpressionDefaults, LoggingConfig
2024-10-14 20:23:09 +02:00
2024-10-16 22:13:39 +02:00
LOGGER = logging.getLogger(LoggingConfig.NAME)
2024-10-05 14:01:50 +02:00
class SpritesheetData(TypedDict):
facesize: Tuple[int, int]
2024-10-05 14:01:50 +02:00
position: Tuple[int, int]
class ExtendData(TypedDict):
faceSizeRect: NotRequired[Annotated[List[int], 2]]
faceSize: NotRequired[int]
2024-10-20 21:38:22 +02:00
def fetch_config(chara_id: int) -> SpritesheetData:
url = f"https://api.atlasacademy.io/raw/JP/svtScript?charaId={chara_id}"
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"Loading data for {url}")
2024-10-16 22:13:39 +02:00
response = requests.get(url, timeout=AtlasAPIConfig.TIMEOUT)
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"{response.status_code} - {response.text}")
if not response.ok:
2025-03-29 13:20:43 +01:00
raise ValueError(f"Failed to fetch data for charaId {chara_id}")
2025-03-29 13:20:43 +01:00
resp_json = response.json()
if len(resp_json) == 0:
raise ValueError(f"No data was returned for get given charaId {chara_id}. Please ensure that this is a valid charaId and not the baseSvtId")
resp_data = resp_json[0]
extend_data: ExtendData = resp_data["extendData"]
if "faceSizeRect" in extend_data:
facesize: Tuple[int, int] = tuple(extend_data["faceSizeRect"]) # type: ignore
else:
facesize = tuple(2 * [ extend_data.get("faceSize", ExpressionDefaults.FACESIZE) ]) # type: ignore
position: tuple[int, int] = (resp_data["faceX"], resp_data["faceY"])
returndata: SpritesheetData = {
"facesize": facesize,
"position": position
}
2024-08-09 18:57:33 +02:00
2024-10-14 20:23:09 +02:00
LOGGER.debug(returndata)
return returndata
2024-08-09 18:57:33 +02:00
def fetch_mstsvtjson() -> None:
2024-10-16 22:13:39 +02:00
url = AtlasAPIConfig.MST_SVT_JSON
filelocation = PathConfig.IMAGES / "mstsvt.json"
if filelocation.exists():
2024-10-14 20:23:09 +02:00
LOGGER.info("Found cached asset for mstsvt.json")
return
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"Loading data for {url}")
with open(filelocation, 'wb') as handle:
2024-10-16 22:13:39 +02:00
response = requests.get(url, stream=True, timeout=AtlasAPIConfig.TIMEOUT)
status = response.status_code
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"{response.status_code} - {response.text}")
if status != 200:
raise ValueError("Could not fetch mstsvnt.json from atlas - please check your network connection")
for block in response.iter_content(1024):
if not block:
break
handle.write(block)
def fetch_expression_sheets(tempfolder: pathlib.Path, imageid: int) -> pathlib.Path:
2024-10-16 22:13:39 +02:00
atlasurl_base = f"https://static.atlasacademy.io/{AtlasAPIConfig.REGION}/CharaFigure/{imageid}"
2024-08-09 18:57:33 +02:00
2024-10-18 15:59:18 +02:00
savefolder = tempfolder / str(imageid)
savefolder.mkdir(exist_ok=True, parents=True)
2024-10-05 14:01:50 +02:00
idx, status = 0, 200
while status == 200:
filelocation = savefolder / f"{idx}.png"
postfix = ""
if idx == 1:
postfix = "f"
elif idx > 1:
postfix = f"f{idx}"
if filelocation.exists():
2024-10-14 20:23:09 +02:00
LOGGER.info(f"Found cached asset for {imageid}{postfix}.png")
2024-10-05 14:01:50 +02:00
idx += 1
continue
filename = f"{imageid}{postfix}.png"
atlasurl = f"{atlasurl_base}/{filename}"
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"Loading data for {atlasurl}")
2024-10-05 14:01:50 +02:00
with open(filelocation, 'wb') as handle:
2024-10-16 22:13:39 +02:00
response = requests.get(atlasurl, stream=True, timeout=AtlasAPIConfig.TIMEOUT)
2024-10-05 14:01:50 +02:00
status = response.status_code
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"{response.status_code} - {response.text}")
2025-03-29 13:20:43 +01:00
if status != 200 and postfix == "":
LOGGER.warning(f"There was no expression sheet for the given charaId {imageid} - please ensure that this charaId is valid.")
2024-10-05 14:01:50 +02:00
if status != 200:
continue
for block in response.iter_content(1024):
if not block:
break
handle.write(block)
2024-10-14 20:23:09 +02:00
LOGGER.info(f"Finished downloading {filename}")
2024-10-05 14:01:50 +02:00
idx += 1
p = savefolder / f"{idx}.png"
p.unlink(missing_ok=True)
return savefolder
2024-10-05 14:01:50 +02:00
2024-08-09 18:57:33 +02:00
2024-10-20 21:38:22 +02:00
def fetch_data(servantid: int) -> List[int]:
2024-10-16 22:13:39 +02:00
atlasurl = f"https://api.atlasacademy.io/nice/{AtlasAPIConfig.REGION}/servant/{servantid}?lore=false&lang=en"
2024-08-09 18:57:33 +02:00
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"Loading data for {atlasurl}")
2024-10-16 22:13:39 +02:00
response = requests.get(atlasurl, timeout=AtlasAPIConfig.TIMEOUT)
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"{response.status_code}")
2024-08-09 18:57:33 +02:00
if not response.ok:
2024-10-14 20:23:09 +02:00
LOGGER.debug(f"{response.status_code} - {response.text}")
raise ValueError(f"{response.status_code} - {response.text}")
2024-08-09 18:57:33 +02:00
responsedata = response.json()
svtname = responsedata["name"]
2024-10-20 21:38:22 +02:00
charascripts: List[dict[str, int]] = responsedata["charaScripts"]
chara_ids: List[int] = [chara["id"] for chara in charascripts]
2024-10-05 14:01:50 +02:00
2024-10-14 20:23:09 +02:00
LOGGER.debug(chara_ids)
LOGGER.info(f"{svtname} ({servantid}) - {len(chara_ids)} charaIds")
return chara_ids