diff options
| author | 2024-01-22 17:24:37 +0800 | |
|---|---|---|
| committer | 2024-01-22 17:24:37 +0800 | |
| commit | 8e876af44959309dba2bb3e788da3181a3987ed8 (patch) | |
| tree | 2ddb62a949192aa600f69d71a9cc7626df677263 /src | |
| parent | ca01ccf7b915e0841203a453d1ecdc1647940a89 (diff) | |
| download | ipm-8e876af44959309dba2bb3e788da3181a3987ed8.tar.gz ipm-8e876af44959309dba2bb3e788da3181a3987ed8.zip | |
:sparkles: feat(index): add index operator and improve api with index
Diffstat (limited to 'src')
| -rw-r--r-- | src/ipm/api.py | 21 | ||||
| -rw-r--r-- | src/ipm/models/index.py | 51 |
2 files changed, 68 insertions, 4 deletions
diff --git a/src/ipm/api.py b/src/ipm/api.py index 866355c..12104ac 100644 --- a/src/ipm/api.py +++ b/src/ipm/api.py @@ -1,11 +1,12 @@ from pathlib import Path from .typing import StrPath from .utils import freeze, urlparser, loader -from .models.ipk import InfiniProject, InfiniFrozenPackage -from .models.lock import PackageLock from .exceptions import FileTypeMismatch, TomlLoadFailed, FileNotFoundError from .const import INDEX, STORAGE, SRC_HOME from .logging import info, success, warning, error +from .models.ipk import InfiniProject, InfiniFrozenPackage +from .models.lock import PackageLock +from .models.index import Yggdrasil import toml import shutil @@ -74,8 +75,20 @@ def install(uri: str, index: str = "", echo: bool = False) -> None: lock = PackageLock() if uri.isalpha(): - # TODO - ... + yggdrasil = Yggdrasil(index) + if not lock.get_index(index): + yggdrasil.sync() + lock.add_index(index, yggdrasil.host, yggdrasil.uuid, dump=True) + + if not (remote_ifp := yggdrasil.get(uri)): # TODO 特定版本的捕获 + return warning(f"未能在世界树[{yggdrasil.index}]中搜寻到规则包[{uri}].", echo) + + ifp = loader.load_from_remote( + uri, + baseurl=index + remote_ifp["name"], + filename=remote_ifp["storage"], + echo=echo, + ) elif urlparser.is_valid_url(uri): info(f"检定给定的 URI 地址[{uri}]为远程路径.", echo) filename = uri.rstrip("/").rpartition("/")[-1] diff --git a/src/ipm/models/index.py b/src/ipm/models/index.py new file mode 100644 index 0000000..2dc529e --- /dev/null +++ b/src/ipm/models/index.py @@ -0,0 +1,51 @@ +from pathlib import Path +from urllib.parse import urlparse +from .lock import PackageLock +from ..const import INDEX_PATH +from ..typing import Storage +from ..exceptions import LockLoadFailed + +import requests +import tempfile +import shutil + + +class Yggdrasil: + source_path: Path + + host: str + uuid: str + index: str + lock: PackageLock + + def __init__(self, index: str) -> None: + INDEX_PATH.mkdir(parents=True, exist_ok=True) + self.index = index.rstrip("/") + "/" + + def sync(self, echo: bool = False): # TODO 输出内容 + lock_bytes = requests.get(self.index + "infini.lock").content + + temp_dir = tempfile.TemporaryDirectory() + temp_path = Path(temp_dir.name).resolve() + temp_lock_path = temp_path / "infini.lock" + + temp_lock_file = temp_lock_path.open("wb") + temp_lock_file.write(lock_bytes) + temp_lock_file.close() + + temp_lock = PackageLock(temp_lock_path) + + if "uuid" not in temp_lock.metadata.keys(): + temp_dir.cleanup() + raise LockLoadFailed(f"地址[{self.index}]不是合法的世界树服务器.") + + self.uuid = temp_lock.metadata["uuid"] + self.host = temp_lock.metadata.get("host") or urlparse(self.index).netloc + self.source_path = INDEX_PATH / self.uuid + + self.source_path.mkdir(parents=True, exist_ok=True) + shutil.copy2(temp_lock_path, self.source_path) + self.lock = PackageLock(self.source_path / "infini.lock") + + def get(self, name: str, version: str | None = None) -> Storage | None: + return self.lock.get_particular_storage(name, version) |
