updating ba_data

This commit is contained in:
Ayush Saini 2024-11-28 00:23:35 +05:30
parent b0b6865bdf
commit 48af420a73
92 changed files with 3174 additions and 1075 deletions

View file

@ -14,7 +14,26 @@ if TYPE_CHECKING:
# Version is sent to the master-server with all commands. Can be incremented
# if we need to change behavior server-side to go along with client changes.
BACLOUD_VERSION = 8
BACLOUD_VERSION = 13
def asset_file_cache_path(filehash: str) -> str:
"""Given a sha256 hex file hash, return a storage path."""
# We expect a 64 byte hex str with only lowercase letters and
# numbers. Note to self: I considered base64 hashes to save space
# but then remembered that lots of filesystems out there ignore case
# so that would not end well.
assert len(filehash) == 64
assert filehash.islower()
assert filehash.isalnum()
# Split into a few levels of directories to keep directory listings
# and operations reasonable. This will give 256 top level dirs, each
# with 256 subdirs. So if we have 65,536 files in our cache then
# dirs will average 1 file each. That seems like a reasonable spread
# I think.
return f'{filehash[:2]}/{filehash[2:4]}/{filehash[4:]}'
@ioprepped
@ -32,7 +51,6 @@ class RequestData:
@ioprepped
@dataclass
class ResponseData:
# noinspection PyUnresolvedReferences
"""Response sent from the bacloud server to the client.
Attributes:
@ -49,11 +67,13 @@ class ResponseData:
It should be added to end_command args as 'manifest'.
uploads: If present, client should upload the requested files (arg1)
individually to a server command (arg2) with provided args (arg3).
uploads_inline: If present, a list of pathnames that should be base64
gzipped and uploaded to an 'uploads_inline' dict in end_command args.
uploads_inline: If present, a list of pathnames that should be gzipped
and uploaded to an 'uploads_inline' bytes dict in end_command args.
This should be limited to relatively small files.
deletes: If present, file paths that should be deleted on the client.
downloads_inline: If present, pathnames mapped to base64 gzipped data to
downloads: If present, describes files the client should individually
request from the server if not already present on the client.
downloads_inline: If present, pathnames mapped to gzipped data to
be written to the client. This should only be used for relatively
small files as they are all included inline as part of the response.
dir_prune_empty: If present, all empty dirs under this one should be
@ -69,6 +89,39 @@ class ResponseData:
end_command: If present, this command is run with these args at the end
of response processing.
"""
@ioprepped
@dataclass
class Downloads:
"""Info about downloads included in a response."""
@ioprepped
@dataclass
class Entry:
"""Individual download."""
path: Annotated[str, IOAttrs('p')]
# Args include with this particular request (combined with
# baseargs).
args: Annotated[dict[str, str], IOAttrs('a')]
# TODO: could add a hash here if we want the client to
# verify hashes.
# If present, will be prepended to all entry paths via os.path.join.
basepath: Annotated[str | None, IOAttrs('p')]
# Server command that should be called for each download. The
# server command is expected to respond with a downloads_inline
# containing a single 'default' entry. In the future this may
# be expanded to a more streaming-friendly process.
cmd: Annotated[str, IOAttrs('c')]
# Args that should be included with all download requests.
baseargs: Annotated[dict[str, str], IOAttrs('a')]
# Everything that should be downloaded.
entries: Annotated[list[Entry], IOAttrs('e')]
message: Annotated[str | None, IOAttrs('m', store_default=False)] = None
message_end: Annotated[str, IOAttrs('m_end', store_default=False)] = '\n'
error: Annotated[str | None, IOAttrs('e', store_default=False)] = None
@ -87,8 +140,11 @@ class ResponseData:
deletes: Annotated[
list[str] | None, IOAttrs('dlt', store_default=False)
] = None
downloads: Annotated[
Downloads | None, IOAttrs('dl', store_default=False)
] = None
downloads_inline: Annotated[
dict[str, str] | None, IOAttrs('dinl', store_default=False)
dict[str, bytes] | None, IOAttrs('dinl', store_default=False)
] = None
dir_prune_empty: Annotated[
str | None, IOAttrs('dpe', store_default=False)