distro: refactor BinaryPackage, Repo and Distro into generics for Local and Remote

This commit is contained in:
InsanePrawn 2022-09-01 03:57:54 +02:00
parent dbe3dc91a3
commit bf420a73be
5 changed files with 109 additions and 41 deletions

View file

@ -5,7 +5,11 @@ import tarfile
import tempfile
import urllib.request
from .package import BinaryPackage
from typing import Generic, TypeVar
from .package import BinaryPackage, LocalPackage, RemotePackage
BinaryPackageType = TypeVar('BinaryPackageType', bound=BinaryPackage)
def resolve_url(url_template, repo_name: str, arch: str):
@ -24,11 +28,11 @@ class RepoInfo:
self.options.update(options)
class Repo(RepoInfo):
class Repo(RepoInfo, Generic[BinaryPackageType]):
name: str
resolved_url: str
arch: str
packages: dict[str, BinaryPackage]
packages: dict[str, BinaryPackageType]
remote: bool
scanned: bool = False
@ -38,26 +42,28 @@ class Repo(RepoInfo):
def scan(self):
self.resolved_url = self.resolve_url()
self.remote = not self.resolved_url.startswith('file://')
uri = f'{self.resolved_url}/{self.name}.db'
path = ''
if self.remote:
logging.info(f'Downloading repo file from {uri}')
with urllib.request.urlopen(uri) as request:
fd, path = tempfile.mkstemp()
with open(fd, 'wb') as writable:
writable.write(request.read())
else:
path = uri.split('file://')[1]
path = self.acquire_db_file()
logging.debug(f'Parsing repo file at {path}')
with tarfile.open(path) as index:
for node in index.getmembers():
if os.path.basename(node.name) == 'desc':
logging.debug(f'Parsing desc file for {os.path.dirname(node.name)}')
pkg = BinaryPackage.parse_desc(index.extractfile(node).read().decode(), self.resolved_url)
fd = index.extractfile(node)
assert fd
pkg = self._parse_desc(fd.read().decode())
self.packages[pkg.name] = pkg
self.scanned = True
def _parse_desc(self, desc_text: str): # can't annotate the type properly :(
raise NotImplementedError()
def parse_desc(self, desc_text: str) -> BinaryPackageType:
return self._parse_desc(desc_text)
def acquire_db_file(self) -> str:
raise NotImplementedError
def __init__(self, name: str, url_template: str, arch: str, options={}, scan=False):
self.packages = {}
self.name = name
@ -76,3 +82,27 @@ class Repo(RepoInfo):
def get_RepoInfo(self):
return RepoInfo(url_template=self.url_template, options=self.options)
class LocalRepo(Repo[LocalPackage]):
def _parse_desc(self, desc_text: str) -> LocalPackage:
return LocalPackage.parse_desc(desc_text, resolved_repo_url=self.resolved_url)
def acquire_db_file(self) -> str:
return f'{self.resolved_url}/{self.name}.db'.split('file://')[1]
class RemoteRepo(Repo[RemotePackage]):
def _parse_desc(self, desc_text: str) -> RemotePackage:
return RemotePackage.parse_desc(desc_text, resolved_repo_url=self.resolved_url)
def acquire_db_file(self) -> str:
uri = f'{self.resolved_url}/{self.name}.db'
logging.info(f'Downloading repo file from {uri}')
with urllib.request.urlopen(uri) as request:
fd, path = tempfile.mkstemp()
with open(fd, 'wb') as writable:
writable.write(request.read())
return path