diff options
Diffstat (limited to 'kvmd/plugins/msd/otg/__init__.py')
-rw-r--r-- | kvmd/plugins/msd/otg/__init__.py | 76 |
1 files changed, 30 insertions, 46 deletions
diff --git a/kvmd/plugins/msd/otg/__init__.py b/kvmd/plugins/msd/otg/__init__.py index 50f737a6..7347a733 100644 --- a/kvmd/plugins/msd/otg/__init__.py +++ b/kvmd/plugins/msd/otg/__init__.py @@ -57,8 +57,7 @@ from .. import BaseMsd from .. import MsdFileReader from .. import MsdFileWriter -from . import fs - +from .storage import Storage from .drive import Drive @@ -67,9 +66,15 @@ from .drive import Drive class _DriveImage: name: str path: str - size: int complete: bool in_storage: bool + size: int = dataclasses.field(default=0) + + def __post_init__(self) -> None: + try: + object.__setattr__(self, "size", max(os.path.getsize(self.path), 0)) + except Exception as err: + get_logger().warning("Can't get size of file %s: %s", self.path, err) @dataclasses.dataclass(frozen=True) @@ -151,16 +156,13 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes self.__write_chunk_size = write_chunk_size self.__sync_chunk_size = sync_chunk_size - self.__storage_path = os.path.normpath(storage_path) - self.__images_path = os.path.join(self.__storage_path, "images") - self.__meta_path = os.path.join(self.__storage_path, "meta") - self.__remount_cmd = remount_cmd self.__initial_image: str = initial["image"] self.__initial_cdrom: bool = initial["cdrom"] self.__drive = Drive(gadget, instance=0, lun=0) + self.__storage = Storage(storage_path) self.__reader: (MsdFileReader | None) = None self.__writer: (MsdFileWriter | None) = None @@ -206,7 +208,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes if self.__writer: # При загрузке файла показываем актуальную статистику вручную storage["uploading"] = self.__writer.get_state() - space = fs.get_fs_space(self.__storage_path, fatal=False) + space = self.__storage.get_space(fatal=False) if space: storage.update(dataclasses.asdict(space)) else: @@ -338,7 +340,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes if self.__state.vd.connected or self.__drive.get_image_path(): raise MsdConnectedError() - path = os.path.join(self.__images_path, name) + path = self.__storage.get_image_path(name) if name not in self.__state.storage.images or not os.path.exists(path): raise MsdUnknownImageError() @@ -369,12 +371,12 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes if self.__state.vd.connected or self.__drive.get_image_path(): raise MsdConnectedError() - path = os.path.join(self.__images_path, name) + path = self.__storage.get_image_path(name) if name in self.__state.storage.images or os.path.exists(path): raise MsdImageExistsError() await self.__remount_rw(True) - self.__set_image_complete(name, False) + self.__storage.set_image_complete(name, False) self.__writer = await MsdFileWriter( notifier=self.__notifier, @@ -386,7 +388,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes self.__notifier.notify() yield self.__writer - self.__set_image_complete(name, self.__writer.is_complete()) + self.__storage.set_image_complete(name, self.__writer.is_complete()) finally: if remove_incomplete and self.__writer and not self.__writer.is_complete(): @@ -424,7 +426,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes await self.__remount_rw(True) os.remove(image.path) - self.__set_image_complete(name, False) + self.__storage.set_image_complete(name, False) await self.__remount_rw(False, fatal=False) # ===== @@ -453,9 +455,10 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes await asyncio.sleep(5) with Inotify() as inotify: - inotify.watch(self.__images_path, InotifyMask.ALL_MODIFY_EVENTS) - inotify.watch(self.__meta_path, InotifyMask.ALL_MODIFY_EVENTS) - for path in self.__drive.get_watchable_paths(): + for path in [ + *self.__storage.get_watchable_paths(), + *self.__drive.get_watchable_paths(), + ]: inotify.watch(path, InotifyMask.ALL_MODIFY_EVENTS) # После установки вотчеров еще раз проверяем стейт, чтобы ничего не потерять @@ -522,7 +525,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes async def __setup_initial(self) -> None: if self.__initial_image: logger = get_logger(0) - path = os.path.join(self.__images_path, self.__initial_image) + path = self.__storage.get_image_path(self.__initial_image) if os.path.exists(path): logger.info("Setting up initial image %r ...", self.__initial_image) try: @@ -538,19 +541,14 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes def __get_storage_state(self) -> _StorageState: images: dict[str, _DriveImage] = {} - for name in os.listdir(self.__images_path): - path = os.path.join(self.__images_path, name) - if os.path.exists(path): - size = fs.get_file_size(path) - if size >= 0: - images[name] = _DriveImage( - name=name, - path=path, - size=size, - complete=self.__is_image_complete(name), - in_storage=True, - ) - space = fs.get_fs_space(self.__storage_path, fatal=True) + for name in self.__storage.get_images(): + images[name] = _DriveImage( + name=name, + path=self.__storage.get_image_path(name), + complete=self.__storage.is_image_complete(name), + in_storage=True, + ) + space = self.__storage.get_space(fatal=True) assert space return _StorageState( size=space.size, @@ -563,12 +561,11 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes path = self.__drive.get_image_path() if path: name = os.path.basename(path) - in_storage = (os.path.dirname(path) == self.__images_path) + in_storage = self.__storage.is_image_path_in_storage(path) image = _DriveImage( name=name, path=path, - size=max(fs.get_file_size(path), 0), - complete=(self.__is_image_complete(name) if in_storage else True), + complete=(self.__storage.is_image_complete(name) if in_storage else True), in_storage=in_storage, ) return _DriveState( @@ -579,19 +576,6 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes # ===== - def __is_image_complete(self, name: str) -> bool: - return os.path.exists(os.path.join(self.__meta_path, name + ".complete")) - - def __set_image_complete(self, name: str, flag: bool) -> None: - path = os.path.join(self.__meta_path, name + ".complete") - if flag: - open(path, "w").close() # pylint: disable=consider-using-with - else: - if os.path.exists(path): - os.remove(path) - - # ===== - async def __remount_rw(self, rw: bool, fatal: bool=True) -> None: if not (await aiohelpers.remount("MSD", self.__remount_cmd, rw)): if fatal: |