Added streaming up- and downloads, fixed file sizes and added a (not working) dashboard

This commit is contained in:
Mawoka
2023-05-29 16:24:38 +02:00
parent ef73234606
commit a8b59ce6f5
17 changed files with 414 additions and 147 deletions
+20 -43
View File
@@ -2,20 +2,17 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from io import BytesIO
from typing import Optional
from typing import Optional, BinaryIO
from .deta_storage import DetaStorage
from .local_storage import LocalStorage
from .s3_storage import S3Storage
from typing import Generator
class Storage:
def __init__(
self,
backend: str,
deta_key: Optional[str],
deta_id: Optional[str],
storage_path: Optional[str],
access_key: str | None = None,
secret_key: str | None = None,
@@ -23,65 +20,45 @@ class Storage:
base_url: str | None = None,
):
self.backend = backend
self.deta_key: str | None = deta_key
self.deta_id: str | None = deta_id
# self.deta_base_url = f"https://drive.deta.sh/v1/{deta_id}/classquiz1"
self.access_key = access_key
self.secret_key = secret_key
self.bucket_name = bucket_name
self.base_url = base_url
self.deta_instance = None
if backend == "deta":
if deta_key is None or deta_id is None:
raise ValueError("deta_key and deta_id must be provided")
if self.base_url is None:
self.base_url = f"https://drive.deta.sh/v1/{deta_id}/classquiz1"
self.deta_instance = DetaStorage(
deta_base_url=self.base_url,
deta_key=self.deta_key,
deta_id=self.deta_id,
)
self.instance: LocalStorage | S3Storage | None = None
elif backend == "local":
if backend == "local":
if storage_path is None:
raise ValueError("storage_path must be provided")
else:
self.local_instance = LocalStorage(base_path=storage_path)
self.instance = LocalStorage(base_path=storage_path)
elif backend == "s3":
if access_key is None or secret_key is None or bucket_name is None or base_url is None:
raise ValueError("Not all parameters given")
self.s3_instance = S3Storage(
self.instance = S3Storage(
base_url=base_url, access_key=access_key, secret_key=secret_key, bucket_name=bucket_name
)
else:
raise NotImplementedError(f"Backend {backend} not implemented")
async def download(self, file_name: str) -> BytesIO | None:
if self.backend == "deta":
return await self.deta_instance.download(file_name)
elif self.backend == "local":
return await self.local_instance.get_file(file_name)
elif self.backend == "s3":
return await self.s3_instance.download(file_name)
async def download(self, file_name: str) -> Generator | None:
"""
No support for s3 since it doesn't make sense relaying the traffic through this backend
:param file_name:
:return:
"""
yield self.instance.download(file_name)
async def upload(self, file_name: str, file_data: bytes) -> None:
if self.backend == "deta":
return await self.deta_instance.upload(file=file_data, file_name=file_name)
elif self.backend == "local":
return await self.local_instance.write_file(file_name=file_name, data=file_data)
elif self.backend == "s3":
return await self.s3_instance.upload(file=file_data, file_name=file_name)
async def upload(self, file_name: str, file_data: BinaryIO) -> None:
return await self.instance.upload(file=file_data, file_name=file_name)
async def delete(self, file_names: [str]) -> None:
if self.backend == "deta":
return await self.deta_instance.delete(file_names=file_names)
elif self.backend == "local":
return await self.local_instance.delete_file(file_names=file_names)
elif self.backend == "s3":
return await self.s3_instance.delete(file_names=file_names)
return await self.instance.delete(file_names=file_names)
async def get_url(self, file_name: str, expiry: int) -> str:
if self.backend == "s3":
return self.s3_instance.get_url(file_name=file_name, expire=expiry)
return self.instance.get_url(file_name=file_name, expire=expiry)
async def get_file_size(self, file_name: str) -> int | None:
return self.instance.size(file_name)