1
0
Fork 0
mirror of https://github.com/ldericher/fftcgtool synced 2025-01-15 15:02:59 +00:00
fftcgtool/fftcgtool/carddb.py
2021-09-08 23:44:51 +02:00

121 lines
3.3 KiB
Python

from __future__ import annotations
import io
import json
import pickle
import zipfile
from os import PathLike
from typing import IO
import requests
from .card import Card
from .cards import Cards
from .code import Code
from .language import API_LANGS
class CardDB:
_instance: CardDB = None
_cards: dict[Code, Card]
_face_to_url: dict[str, str]
_DB_FILE_NAME = "cards.pickle"
_MAPPING_FILE_NAME = "face_to_url.json"
def __new__(cls, *more) -> CardDB:
if CardDB._instance is None:
CardDB._instance = object.__new__(CardDB)
return CardDB._instance
def __init__(self, db_url: str = None):
if db_url is not None:
res = requests.get(db_url, stream=True)
if not res.ok:
raise ValueError("Invalid URL given to CardDB!")
self._load(io.BytesIO(res.content))
def _load(self, db: str | PathLike[str] | IO[bytes]):
try:
# unpickle db file
with zipfile.ZipFile(db, "r") as zip_file:
# cards db
with zip_file.open(CardDB._DB_FILE_NAME, "r") as file:
self._cards = pickle.load(file)
# face_to_url mapping
with zip_file.open(CardDB._MAPPING_FILE_NAME, "r") as file:
self._face_to_url = json.load(file)
except FileNotFoundError:
self._cards = {}
self._face_to_url = {}
def __contains__(self, item: Code) -> bool:
return item in self._cards
def __getitem__(self, code: Code) -> Card:
return self._cards[code]
def get_face_url(self, face: str) -> str:
if face in self._face_to_url:
return self._face_to_url[face]
else:
return face
def save(self) -> None:
return
def update(self, cards: Cards) -> None:
return
def upload_prompt(self) -> None:
return
class RWCardDB(CardDB):
__db_path: PathLike[str]
def __new__(cls, *more) -> RWCardDB:
if CardDB._instance is None:
CardDB._instance = object.__new__(RWCardDB)
return CardDB._instance
def __init__(self, db_path: str | PathLike[str] = None):
super().__init__(None)
if db_path is not None:
self.__db_path = db_path
self._load(self.__db_path)
def save(self) -> None:
with zipfile.ZipFile(self.__db_path, "w", compression=zipfile.ZIP_LZMA) as zip_file:
# cards db
with zip_file.open(CardDB._DB_FILE_NAME, "w") as file:
pickle.dump(self._cards, file)
# face_to_url mapping
with zip_file.open(CardDB._MAPPING_FILE_NAME, "w") as file:
file.write(json.dumps(self._face_to_url, indent=2).encode("utf-8"))
def update(self, cards: Cards) -> None:
for card in cards:
self._cards[card.code] = card
def upload_prompt(self) -> None:
faces = list(set([
card[lang].face
for card in self._cards.values()
for lang in API_LANGS
if card[lang].face
]))
faces.sort()
for face in faces:
if face not in self._face_to_url:
face_url = input(f"Upload '{face}' and paste URL: ")
if face_url:
self._face_to_url[face] = face_url