diff options
author | Maxim Devaev <[email protected]> | 2022-07-24 16:16:45 +0300 |
---|---|---|
committer | Maxim Devaev <[email protected]> | 2022-07-24 16:16:45 +0300 |
commit | 1055dadcb98b50c7ecbaa6604ec980f2a19c6ba8 (patch) | |
tree | c5b00dd6fd684ca8d67d188311a7598c6fee295c | |
parent | 1564c6872739b64754ca548e5f58248465c31810 (diff) |
msd: downloading status api
-rw-r--r-- | kvmd/plugins/msd/__init__.py | 36 | ||||
-rw-r--r-- | kvmd/plugins/msd/otg/__init__.py | 8 |
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() |