refactoring

This commit is contained in:
Devaev Maxim
2018-07-13 22:20:15 +00:00
parent 0a7eafa256
commit 0ac396f61c
4 changed files with 37 additions and 37 deletions

View File

@@ -5,7 +5,8 @@ from typing import Type
# ===== # =====
class RegionIsBusyError(Exception): class RegionIsBusyError(Exception):
pass def __init__(self) -> None:
super().__init__("Performing another operation, please try again later")
class AioExclusiveRegion: class AioExclusiveRegion:

View File

@@ -10,8 +10,7 @@ from . import gpio
# ===== # =====
class AtxIsBusy(aioregion.RegionIsBusyError): class AtxIsBusy(aioregion.RegionIsBusyError):
def __init__(self) -> None: pass
super().__init__("Performing another operation, please try again later")
class Atx: class Atx:

View File

@@ -21,37 +21,36 @@ from .logging import get_logger
# ===== # =====
class MassStorageError(Exception): class MsdError(Exception):
pass pass
class MassStorageOperationError(MassStorageError): class MsdOperationError(MsdError):
pass pass
class IsNotOperationalError(MassStorageOperationError): class MsdIsNotOperationalError(MsdOperationError):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("Missing path for mass-storage device") super().__init__("Missing path for mass-storage device")
class AlreadyConnectedToPcError(MassStorageOperationError): class MsdAlreadyConnectedToPcError(MsdOperationError):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("Mass-storage is already connected to Server") super().__init__("Mass-storage is already connected to Server")
class AlreadyConnectedToKvmError(MassStorageOperationError): class MsdAlreadyConnectedToKvmError(MsdOperationError):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("Mass-storage is already connected to KVM") super().__init__("Mass-storage is already connected to KVM")
class IsNotConnectedToKvmError(MassStorageOperationError): class MsdIsNotConnectedToKvmError(MsdOperationError):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__("Mass-storage is not connected to KVM") super().__init__("Mass-storage is not connected to KVM")
class IsBusyError(MassStorageOperationError, aioregion.RegionIsBusyError): class MsdIsBusyError(MsdOperationError, aioregion.RegionIsBusyError):
def __init__(self) -> None: pass
super().__init__("Mass-storage is busy (write in progress)")
# ===== # =====
@@ -156,7 +155,7 @@ def _explore_device(device_path: str) -> Optional[_MassStorageDeviceInfo]:
def _msd_operated(method: Callable) -> Callable: def _msd_operated(method: Callable) -> Callable:
async def wrap(self: "MassStorageDevice", *args: Any, **kwargs: Any) -> Any: async def wrap(self: "MassStorageDevice", *args: Any, **kwargs: Any) -> Any:
if not self._device_path: # pylint: disable=protected-access if not self._device_path: # pylint: disable=protected-access
IsNotOperationalError() MsdIsNotOperationalError()
return (await method(self, *args, **kwargs)) return (await method(self, *args, **kwargs))
return wrap return wrap
@@ -177,8 +176,8 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
self.__loop = loop self.__loop = loop
self.__device_info: Optional[_MassStorageDeviceInfo] = None self.__device_info: Optional[_MassStorageDeviceInfo] = None
self.__region = aioregion.AioExclusiveRegion(IsBusyError) self.__region = aioregion.AioExclusiveRegion(MsdIsBusyError)
self._device_file: Optional[aiofiles.base.AiofilesContextManager] = None self.__device_file: Optional[aiofiles.base.AiofilesContextManager] = None
self.__written = 0 self.__written = 0
logger = get_logger(0) logger = get_logger(0)
@@ -188,7 +187,7 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
logger.info("Enabled image metadata writing") logger.info("Enabled image metadata writing")
loop.run_until_complete(self.connect_to_kvm(no_delay=True)) loop.run_until_complete(self.connect_to_kvm(no_delay=True))
except Exception as err: except Exception as err:
if isinstance(err, MassStorageError): if isinstance(err, MsdError):
log = logger.error log = logger.error
else: else:
log = logger.exception log = logger.exception
@@ -201,7 +200,7 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
async def connect_to_kvm(self, no_delay: bool=False) -> None: async def connect_to_kvm(self, no_delay: bool=False) -> None:
with self.__region: with self.__region:
if self.__device_info: if self.__device_info:
raise AlreadyConnectedToKvmError() raise MsdAlreadyConnectedToKvmError()
# TODO: disable gpio # TODO: disable gpio
if not no_delay: if not no_delay:
await asyncio.sleep(self.__init_delay) await asyncio.sleep(self.__init_delay)
@@ -212,7 +211,7 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
async def connect_to_pc(self) -> None: async def connect_to_pc(self) -> None:
with self.__region: with self.__region:
if not self.__device_info: if not self.__device_info:
raise AlreadyConnectedToPcError() raise MsdAlreadyConnectedToPcError()
# TODO: enable gpio # TODO: enable gpio
self.__device_info = None self.__device_info = None
get_logger().info("Mass-storage device switched to Server") get_logger().info("Mass-storage device switched to Server")
@@ -225,7 +224,7 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
return { return {
"in_operate": bool(self._device_path), "in_operate": bool(self._device_path),
"connected_to": ("kvm" if self.__device_info else "server"), "connected_to": ("kvm" if self.__device_info else "server"),
"busy": bool(self._device_file), "busy": bool(self.__device_file),
"written": self.__written, "written": self.__written,
"info": info, "info": info,
} }
@@ -238,19 +237,19 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
async def __aenter__(self) -> "MassStorageDevice": async def __aenter__(self) -> "MassStorageDevice":
self.__region.enter() self.__region.enter()
if not self.__device_info: if not self.__device_info:
raise IsNotConnectedToKvmError() raise MsdIsNotConnectedToKvmError()
self._device_file = await aiofiles.open(self.__device_info.path, mode="w+b", buffering=0) self.__device_file = await aiofiles.open(self.__device_info.path, mode="w+b", buffering=0)
self.__written = 0 self.__written = 0
return self return self
async def write_image_info(self, name: str, complete: bool) -> None: async def write_image_info(self, name: str, complete: bool) -> None:
assert self._device_file assert self.__device_file
assert self.__device_info assert self.__device_info
if self.__write_meta: if self.__write_meta:
if self.__device_info.size - self.__written > _IMAGE_INFO_SIZE: if self.__device_info.size - self.__written > _IMAGE_INFO_SIZE:
await self._device_file.seek(self.__device_info.size - _IMAGE_INFO_SIZE) await self.__device_file.seek(self.__device_info.size - _IMAGE_INFO_SIZE)
await self.__write_to_device_file(_make_image_info_bytes(name, self.__written, complete)) await self.__write_to_device_file(_make_image_info_bytes(name, self.__written, complete))
await self._device_file.seek(0) await self.__device_file.seek(0)
await self.__load_device_info() await self.__load_device_info()
else: else:
get_logger().error("Can't write image info because device is full") get_logger().error("Can't write image info because device is full")
@@ -272,24 +271,24 @@ class MassStorageDevice: # pylint: disable=too-many-instance-attributes
self.__region.exit() self.__region.exit()
async def __write_to_device_file(self, data: bytes) -> None: async def __write_to_device_file(self, data: bytes) -> None:
assert self._device_file assert self.__device_file
await self._device_file.write(data) await self.__device_file.write(data)
await self._device_file.flush() await self.__device_file.flush()
await self.__loop.run_in_executor(None, os.fsync, self._device_file.fileno()) await self.__loop.run_in_executor(None, os.fsync, self.__device_file.fileno())
async def __load_device_info(self) -> None: async def __load_device_info(self) -> None:
device_info = await self.__loop.run_in_executor(None, _explore_device, self._device_path) device_info = await self.__loop.run_in_executor(None, _explore_device, self._device_path)
if not device_info: if not device_info:
raise MassStorageError("Can't explore device %r" % (self._device_path)) raise MsdError("Can't explore device %r" % (self._device_path))
self.__device_info = device_info self.__device_info = device_info
async def __close_device_file(self) -> None: async def __close_device_file(self) -> None:
try: try:
if self._device_file: if self.__device_file:
get_logger().info("Closing mass-storage device file ...") get_logger().info("Closing mass-storage device file ...")
await self._device_file.close() await self.__device_file.close()
except Exception: except Exception:
get_logger().exception("Can't close mass-storage device file") get_logger().exception("Can't close mass-storage device file")
# TODO: reset device file # TODO: reset device file
self._device_file = None self.__device_file = None
self.__written = 0 self.__written = 0

View File

@@ -18,7 +18,7 @@ from .hid import Hid
from .atx import Atx from .atx import Atx
from .msd import MassStorageOperationError from .msd import MsdOperationError
from .msd import MassStorageDevice from .msd import MassStorageDevice
from .streamer import Streamer from .streamer import Streamer
@@ -47,10 +47,11 @@ def _json(result: Optional[Dict]=None, status: int=200) -> aiohttp.web.Response:
def _json_exception(msg: str, err: Exception, status: int) -> aiohttp.web.Response: def _json_exception(msg: str, err: Exception, status: int) -> aiohttp.web.Response:
get_logger().error("%s: %s", msg, err) msg = "%s: %s" % (msg, err)
get_logger().error(msg)
return _json({ return _json({
"error": type(err).__name__, "error": type(err).__name__,
"error_msg": str(err), "error_msg": msg,
}, status=status) }, status=status)
@@ -65,7 +66,7 @@ def _wrap_exceptions_for_web(msg: str) -> Callable:
return (await method(self, request)) return (await method(self, request))
except RegionIsBusyError as err: except RegionIsBusyError as err:
return _json_exception(msg, err, 409) return _json_exception(msg, err, 409)
except (BadRequest, MassStorageOperationError) as err: except (BadRequest, MsdOperationError) as err:
return _json_exception(msg, err, 400) return _json_exception(msg, err, 400)
return wrap return wrap
return make_wrapper return make_wrapper
@@ -227,7 +228,7 @@ class Server: # pylint: disable=too-many-instance-attributes
await self.__broadcast_event("msd_state", state="free") # type: ignore await self.__broadcast_event("msd_state", state="free") # type: ignore
finally: finally:
if written != 0: if written != 0:
logger.info("written %d bytes to mass-storage device", written) logger.info("Written %d bytes to mass-storage device", written)
return _json({"written": written}) return _json({"written": written})
async def __streamer_state_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response: async def __streamer_state_handler(self, _: aiohttp.web.Request) -> aiohttp.web.Response: