2021-03-18 09:17:30 -04:00
|
|
|
"""
|
|
|
|
Resources manager for qrm2.
|
|
|
|
---
|
2023-01-29 00:43:56 -05:00
|
|
|
Copyright (C) 2021-2023 classabbyamp, 0x5c
|
2021-03-18 09:17:30 -04:00
|
|
|
|
2021-06-26 20:23:55 -04:00
|
|
|
SPDX-License-Identifier: LiLiQ-Rplus-1.1
|
2021-03-18 09:17:30 -04:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
2022-12-20 05:38:48 -05:00
|
|
|
import httpx
|
2021-03-18 09:17:30 -04:00
|
|
|
|
|
|
|
from utils.resources_models import Index
|
|
|
|
|
|
|
|
|
|
|
|
class ResourcesManager:
|
|
|
|
def __init__(self, basedir: Path, url: str, versions: dict):
|
|
|
|
self.basedir = basedir
|
|
|
|
self.url = url
|
|
|
|
self.versions = versions
|
|
|
|
self.index: Index = self.sync_start(basedir)
|
|
|
|
|
|
|
|
def parse_index(self, index: str):
|
|
|
|
"""Parses the index."""
|
2023-12-10 07:19:45 -05:00
|
|
|
return Index.model_validate_json(index)
|
2021-03-18 09:17:30 -04:00
|
|
|
|
|
|
|
def sync_fetch(self, filepath: str):
|
|
|
|
"""Fetches files in sync mode."""
|
|
|
|
self.print_msg(f"Fetching {filepath}", "sync")
|
2022-12-20 05:38:48 -05:00
|
|
|
resp = httpx.get(self.url + filepath)
|
|
|
|
resp.raise_for_status()
|
|
|
|
r = resp.content
|
|
|
|
resp.close()
|
|
|
|
return r
|
2021-03-18 09:17:30 -04:00
|
|
|
|
|
|
|
def sync_start(self, basedir: Path) -> Index:
|
|
|
|
"""Takes cares of constructing the local resources repository and initialising the RM."""
|
|
|
|
self.print_msg("Initialising ResourceManager", "sync")
|
|
|
|
self.ensure_dir(basedir)
|
|
|
|
try:
|
|
|
|
raw = self.sync_fetch("index.json")
|
|
|
|
new_index: Index = self.parse_index(raw)
|
|
|
|
with (basedir / "index.json").open("wb") as file:
|
|
|
|
file.write(raw)
|
2022-12-20 05:38:48 -05:00
|
|
|
except (httpx.RequestError, OSError) as ex:
|
2021-03-18 09:17:30 -04:00
|
|
|
self.print_msg(f"There was an issue fetching the index: {ex.__class__.__name__}: {ex}", "sync")
|
|
|
|
if (basedir / "index.json").exists():
|
|
|
|
self.print_msg("Old file exist, using old resources", "fallback")
|
|
|
|
with (basedir / "index.json").open("r") as file:
|
|
|
|
old_index = self.parse_index(file.read())
|
|
|
|
for res, ver in self.versions.items():
|
|
|
|
for file in old_index[res][ver]:
|
|
|
|
if not (basedir / file.filename).exists():
|
|
|
|
self.print_msg(f"Error: {file.filename} is missing", "fallback")
|
|
|
|
raise SystemExit(1)
|
|
|
|
return old_index
|
|
|
|
raise SystemExit(1)
|
|
|
|
for res, ver in self.versions.items():
|
|
|
|
for file in new_index[res][ver]:
|
|
|
|
try:
|
|
|
|
with (basedir / file.filename).open("wb") as f:
|
|
|
|
f.write(self.sync_fetch(file.filename))
|
2022-12-20 05:38:48 -05:00
|
|
|
except (httpx.RequestError, OSError) as ex:
|
2021-03-18 09:17:30 -04:00
|
|
|
ex_cls = ex.__class__.__name__
|
|
|
|
self.print_msg(f"There was an issue fetching {file.filename}: {ex_cls}: {ex}", "sync")
|
|
|
|
if not (basedir / file.filename).exists():
|
|
|
|
raise SystemExit(1)
|
|
|
|
self.print_msg("Old file exists, using it", "fallback")
|
|
|
|
return new_index
|
|
|
|
|
|
|
|
def ensure_dir(self, basedir: Path) -> bool:
|
|
|
|
"""Ensures that the resources/ directory is present. Creates as necessary."""
|
|
|
|
if basedir.is_file():
|
|
|
|
raise FileExistsError(f"'{basedir}' is not a directory!")
|
|
|
|
if not basedir.exists():
|
|
|
|
self.print_msg("Creating resources directory")
|
|
|
|
basedir.mkdir()
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def print_msg(self, msg: str, mode: str = None):
|
|
|
|
"""Formats and prints messages for the resources manager."""
|
|
|
|
message = "RM: "
|
|
|
|
message += msg
|
|
|
|
if mode:
|
|
|
|
message += f" ({mode})"
|
|
|
|
print(message)
|