diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ipm/models/index.py | 88 |
1 files changed, 58 insertions, 30 deletions
diff --git a/src/ipm/models/index.py b/src/ipm/models/index.py index 4c9c38b..607f7a2 100644 --- a/src/ipm/models/index.py +++ b/src/ipm/models/index.py @@ -1,74 +1,102 @@ from pathlib import Path +from typing import Any, List, Literal, Optional from ipm.const import INDEX_PATH from ipm.exceptions import LockLoadFailed from ipm.models.lock import PackageLock +from ipm.typing import Dict -import tomlkit import requests import tempfile import shutil +import json class Yggdrasil: - """此对象内所有方法均为示例方法,可以按照需求和开发习惯进行微调""" - - def __init__(self, index: str) -> None: + def __init__(self, index: str, uuid: str) -> None: self.index = index.rstrip("/") + "/" + self._source_path = INDEX_PATH / uuid self._data = self.read() - def read(self) -> tomlkit.TOMLDocument: - """示例方法,读取一个本地的世界树索引文件,这里使用toml只是作为样例""" + def read(self) -> Dict: if not self._source_path.exists(): self._source_path.parent.mkdir(parents=True, exist_ok=True) - return tomlkit.document() - return tomlkit.load(self._source_path.open("r", encoding="utf-8")) + return {} + return json.load(self._source_path.open("r", encoding="utf-8")) def dump(self) -> None: - """示例方法,将修改保存在本地""" - tomlkit.dump(self._data, self._source_path.open("w", encoding="utf-8")) + json.dump(self._data, self._source_path.open("w", encoding="utf-8")) + + @staticmethod + def try_loads(path: Path) -> Dict | Literal[False]: + try: + return json.loads(path.read_text(encoding="utf-8")) + except Exception as e: + print(e) + return False @staticmethod def check(source_path: Path): """检查一个索引文件是否合法""" - raise NotImplementedError + if not (packages := Yggdrasil.try_loads(source_path)): + return False + return packages - def sync(self): - """示例方法,下载或同步索引文件""" + @staticmethod + def init(index: str) -> "Yggdrasil": lock_bytes = requests.get( - self.index + "infini.lock" - ).content # 索引文件地址,这里的lock仅作示例 + index.rstrip("/") + "/" + "json/packages.json" + ).content temp_dir = tempfile.TemporaryDirectory() temp_path = Path(temp_dir.name).resolve() - temp_lock_path = temp_path / "infini.lock" # 本地索引文件地址,这里的lock仅作示例 + temp_lock_path = temp_path / "packages.json" temp_lock_file = temp_lock_path.open("wb") temp_lock_file.write(lock_bytes) temp_lock_file.close() - Yggdrasil.check(temp_lock_path) # 检查索引文件合法性 - - temp_lock = PackageLock(temp_lock_path) + if not (packages := Yggdrasil.check(temp_lock_path)): + raise LockLoadFailed(f"地址 [red]{index}[/] 不是合法的世界树服务器.") - if "uuid" not in temp_lock.metadata.keys(): + if "uuid" not in packages["metadata"].keys(): temp_dir.cleanup() - raise LockLoadFailed(f"地址[{self.index}]不是合法的世界树服务器.") + raise LockLoadFailed(f"地址[{index}]不是合法的世界树服务器.") + uuid = packages["metadata"]["uuid"] - self._source_path = INDEX_PATH / temp_lock.metadata["uuid"] - self._source_path.mkdir(parents=True, exist_ok=True) - - shutil.copy2(temp_lock_path, self._source_path) + source_path = INDEX_PATH / uuid + shutil.copy2(temp_lock_path, source_path) temp_dir.cleanup() - def get_url(self, name: str, version: str) -> str: + lock = PackageLock() + lock.update_index(index, uuid, str(source_path)) + return Yggdrasil(index, uuid) + + def sync(self): + yggdrasil = Yggdrasil.init(self.index) + self._source_path = yggdrasil._source_path + self._data = yggdrasil._data + + def get_url(self, name: str, version: str) -> Optional[str]: """从本地读取规则包下载链接""" - raise NotImplementedError + if name not in self.packages: + return None + for distribution in self.packages[name]["distributions"]: + if distribution["version"] == version: + return distribution["download_url"] - def get_hash(self, name: str, version: str) -> str: + def get_hash(self, name: str, version: str) -> Optional[str]: """从本地获取规则包哈希值""" - raise NotImplementedError + if name not in self.packages: + return None + for distribution in self.packages[name]["distributions"]: + if distribution["version"] == version: + return distribution["hash"] @property def uuid(self) -> str: """世界树唯一标识""" - raise NotImplementedError + return self._data["metadata"]["uuid"] + + @property + def packages(self) -> Dict[str, Any]: + return self._data["packages"] |
