Introduce a `setup` step in the workflow that is responsible of generating the cache folder. This is then used in each download method.
71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
import abc
|
|
import contextlib
|
|
import os
|
|
import json
|
|
import tempfile
|
|
|
|
from . import host
|
|
from .objectstore import ObjectStore
|
|
from .util.types import PathLike
|
|
|
|
|
|
class Source:
|
|
"""
|
|
A single source with is corresponding options.
|
|
"""
|
|
|
|
def __init__(self, info, items, options) -> None:
|
|
self.info = info
|
|
self.items = items or {}
|
|
self.options = options
|
|
|
|
def download(self, mgr: host.ServiceManager, store: ObjectStore, libdir: PathLike):
|
|
source = self.info.name
|
|
cache = os.path.join(store.store, "sources")
|
|
|
|
args = {
|
|
"options": self.options,
|
|
"cache": cache,
|
|
"output": None,
|
|
"checksums": [],
|
|
"libdir": os.fspath(libdir)
|
|
}
|
|
|
|
client = mgr.start(f"source/{source}", self.info.path)
|
|
|
|
with self.make_items_file(store.tmp) as fd:
|
|
fds = [fd]
|
|
reply = client.call_with_fds("download", args, fds)
|
|
|
|
return reply
|
|
|
|
@contextlib.contextmanager
|
|
def make_items_file(self, tmp):
|
|
with tempfile.TemporaryFile("w+", dir=tmp, encoding="utf-8") as f:
|
|
json.dump(self.items, f)
|
|
f.seek(0)
|
|
yield f.fileno()
|
|
|
|
|
|
class SourceService(host.Service):
|
|
"""Source host service"""
|
|
|
|
@abc.abstractmethod
|
|
def download(self, items, cache, options):
|
|
pass
|
|
|
|
def setup(self, cache, content_type):
|
|
self.cache = os.path.join(cache, content_type)
|
|
os.makedirs(self.cache, exist_ok=True)
|
|
|
|
def dispatch(self, method: str, args, fds):
|
|
if method == "download":
|
|
with os.fdopen(fds.steal(0)) as f:
|
|
items = json.load(f)
|
|
|
|
r = self.download(items,
|
|
args["cache"],
|
|
args["options"])
|
|
return r, None
|
|
|
|
raise host.ProtocolError("Unknown method")
|