summaryrefslogtreecommitdiff
path: root/kvmd/plugins/msd/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'kvmd/plugins/msd/__init__.py')
-rw-r--r--kvmd/plugins/msd/__init__.py60
1 files changed, 37 insertions, 23 deletions
diff --git a/kvmd/plugins/msd/__init__.py b/kvmd/plugins/msd/__init__.py
index bddf0ef8..dbe3ff90 100644
--- a/kvmd/plugins/msd/__init__.py
+++ b/kvmd/plugins/msd/__init__.py
@@ -104,6 +104,19 @@ class MsdRwNotSupported(MsdOperationError):
# =====
+class BaseMsdReader:
+ def get_state(self) -> Dict:
+ raise NotImplementedError()
+
+ def get_total_size(self) -> int:
+ raise NotImplementedError()
+
+ async def read_chunked(self) -> AsyncGenerator[bytes, None]:
+ if self is not None: # XXX: Vulture and pylint hack
+ raise NotImplementedError()
+ yield
+
+
class BaseMsd(BasePlugin):
async def get_state(self) -> Dict:
raise NotImplementedError()
@@ -134,14 +147,11 @@ class BaseMsd(BasePlugin):
raise NotImplementedError()
@contextlib.asynccontextmanager
- async def read_image(self, name: str) -> AsyncGenerator[int, None]:
+ async def read_image(self, name: str) -> AsyncGenerator[BaseMsdReader, None]:
_ = name
if self is not None: # XXX: Vulture and pylint hack
raise NotImplementedError()
- yield 1
-
- async def read_image_chunk(self) -> bytes:
- raise NotImplementedError()
+ yield BaseMsdReader()
@contextlib.asynccontextmanager
async def write_image(self, name: str, size: int, remove_incomplete: Optional[bool]) -> AsyncGenerator[int, None]:
@@ -159,7 +169,7 @@ class BaseMsd(BasePlugin):
raise NotImplementedError()
-class MsdImageReader: # pylint: disable=too-many-instance-attributes
+class MsdFileReader(BaseMsdReader): # 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)
@@ -171,10 +181,6 @@ class MsdImageReader: # pylint: disable=too-many-instance-attributes
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,
@@ -182,25 +188,33 @@ class MsdImageReader: # pylint: disable=too-many-instance-attributes
"readed": self.__readed,
}
- async def open(self) -> "MsdImageReader":
+ def get_total_size(self) -> int:
+ assert self.__file is not None
+ return self.__file_size
+
+ async def read_chunked(self) -> AsyncGenerator[bytes, None]:
+ assert self.__file is not None
+ while True:
+ chunk = await self.__file.read(self.__chunk_size) # type: ignore
+ if not chunk:
+ break
+
+ 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()
+
+ yield chunk
+
+ async def open(self) -> "MsdFileReader":
assert self.__file is None
get_logger(1).info("Reading %r image from MSD ...", self.__name)
self.__file_size = os.stat(self.__path).st_size
self.__file = await aiofiles.open(self.__path, mode="rb") # type: ignore
return self
- async def read(self) -> bytes:
- assert self.__file is not None
- 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()