summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ipm/api.py21
-rw-r--r--src/ipm/models/index.py51
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)