summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2022-07-24 16:16:45 +0300
committerMaxim Devaev <[email protected]>2022-07-24 16:16:45 +0300
commit1055dadcb98b50c7ecbaa6604ec980f2a19c6ba8 (patch)
treec5b00dd6fd684ca8d67d188311a7598c6fee295c
parent1564c6872739b64754ca548e5f58248465c31810 (diff)
msd: downloading status api
-rw-r--r--kvmd/plugins/msd/__init__.py36
-rw-r--r--kvmd/plugins/msd/otg/__init__.py8
2 files changed, 34 insertions, 10 deletions
diff --git a/kvmd/plugins/msd/__init__.py b/kvmd/plugins/msd/__init__.py
index b830b0a9..9f120919 100644
--- a/kvmd/plugins/msd/__init__.py
+++ b/kvmd/plugins/msd/__init__.py
@@ -155,14 +155,28 @@ class BaseMsd(BasePlugin):
raise NotImplementedError()
-class MsdImageReader:
- def __init__(self, path: str, chunk_size: int) -> None:
+class MsdImageReader: # pylint: disable=too-many-instance-attributes
+ def __init__(self, notifier: aiotools.AioNotifier, path: str, chunk_size: int) -> None:
+ self.__notifier = notifier
self.__name = os.path.basename(path)
self.__path = path
self.__chunk_size = chunk_size
self.__file: Optional[aiofiles.base.AiofilesContextManager] = None
- self.__file_size: int = 0
+ self.__file_size = 0
+ self.__readed = 0
+ self.__tick = 0.0
+
+ def get_size(self) -> int:
+ assert self.__file is not None
+ return self.__file_size
+
+ def get_state(self) -> Dict:
+ return {
+ "name": self.__name,
+ "size": self.__file_size,
+ "readed": self.__readed,
+ }
async def open(self) -> "MsdImageReader":
assert self.__file is None
@@ -171,18 +185,22 @@ class MsdImageReader:
self.__file = await aiofiles.open(self.__path, mode="rb") # type: ignore
return self
- def get_size(self) -> int:
- assert self.__file is not None
- return self.__file_size
-
async def read(self) -> bytes:
assert self.__file is not None
- return (await self.__file.read(self.__chunk_size)) # type: ignore
+ chunk = await self.__file.read(self.__chunk_size) # type: ignore
+ self.__readed += len(chunk)
+
+ now = time.monotonic()
+ if self.__tick + 1 < now or self.__readed == self.__file_size:
+ self.__tick = now
+ await self.__notifier.notify()
+
+ return chunk
async def close(self) -> None:
assert self.__file is not None
logger = get_logger()
- logger.info("Closed image reader ...")
+ logger.info("Closing image reader ...")
try:
await self.__file.close() # type: ignore
except Exception:
diff --git a/kvmd/plugins/msd/otg/__init__.py b/kvmd/plugins/msd/otg/__init__.py
index a98924ac..bc2b2f99 100644
--- a/kvmd/plugins/msd/otg/__init__.py
+++ b/kvmd/plugins/msd/otg/__init__.py
@@ -204,6 +204,8 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
del storage["images"][name]["path"]
del storage["images"][name]["in_storage"]
+ storage["downloading"] = (self.__reader.get_state() if self.__reader else None)
+
if self.__writer:
# При загрузке файла показываем актуальную статистику вручную
storage["uploading"] = self.__writer.get_state()
@@ -343,7 +345,11 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
if name not in self.__state.storage.images or not os.path.exists(path):
raise MsdUnknownImageError()
- self.__reader = await MsdImageReader(path, self.__read_chunk_size).open()
+ self.__reader = await MsdImageReader(
+ notifier=self.__notifier,
+ path=path,
+ chunk_size=self.__read_chunk_size,
+ ).open()
yield self.__reader.get_size()