diff --git a/python/common/src/piscsi/file_cmds.py b/python/common/src/piscsi/file_cmds.py index a64298ae..9f696c59 100644 --- a/python/common/src/piscsi/file_cmds.py +++ b/python/common/src/piscsi/file_cmds.py @@ -5,7 +5,6 @@ Module for methods reading from and writing to the file system import logging import asyncio from os import walk, path -from functools import lru_cache from pathlib import PurePath, Path from zipfile import ZipFile, is_zipfile from subprocess import run, Popen, PIPE, CalledProcessError, TimeoutExpired @@ -17,18 +16,15 @@ from re import search import requests -import piscsi_interface_pb2 as proto from piscsi.common_settings import ( CFG_DIR, CONFIG_FILE_SUFFIX, PROPERTIES_SUFFIX, - ARCHIVE_FILE_SUFFIXES, RESERVATIONS, SHELL_ERROR, ) from piscsi.piscsi_cmds import PiscsiCmds from piscsi.return_codes import ReturnCodes -from piscsi.socket_cmds import SocketCmds from util import unarchiver FILE_READ_ERROR = "Unhandled exception when reading file: %s" @@ -41,18 +37,8 @@ class FileCmds: class for methods reading from and writing to the file system """ - def __init__(self, sock_cmd: SocketCmds, piscsi: PiscsiCmds, token=None, locale=None): - self.sock_cmd = sock_cmd + def __init__(self, piscsi: PiscsiCmds): self.piscsi = piscsi - self.token = token - self.locale = locale - - def send_pb_command(self, command): - if logging.getLogger().isEnabledFor(logging.DEBUG): - # TODO: Uncouple/move to common dependency - logging.debug(self.piscsi.format_pb_command(command)) - - return self.sock_cmd.send_pb_command(command.SerializeToString()) # noinspection PyMethodMayBeStatic def list_config_files(self): @@ -87,76 +73,6 @@ class FileCmds: subdir_list.sort() return subdir_list - def list_images(self): - """ - Sends a IMAGE_FILES_INFO command to the server - Returns a (dict) with (bool) status, (str) msg, and (list) of (dict)s files - - """ - command = proto.PbCommand() - command.operation = proto.PbOperation.DEFAULT_IMAGE_FILES_INFO - command.params["token"] = self.token - command.params["locale"] = self.locale - - data = self.send_pb_command(command) - result = proto.PbResult() - result.ParseFromString(data) - - server_info = self.piscsi.get_server_info() - files = [] - for file in result.image_files_info.image_files: - prop_file_path = Path(CFG_DIR) / f"{file.name}.{PROPERTIES_SUFFIX}" - # Add properties meta data for the image, if matching prop file is found - if prop_file_path.exists(): - process = self.read_drive_properties(prop_file_path) - prop = process["conf"] - else: - prop = False - - archive_contents = [] - if PurePath(file.name).suffix.lower()[1:] in ARCHIVE_FILE_SUFFIXES: - try: - archive_info = self._get_archive_info( - f"{server_info['image_dir']}/{file.name}", - _cache_extra_key=file.size, - ) - - properties_files = [ - x["path"] - for x in archive_info["members"] - if x["path"].endswith(PROPERTIES_SUFFIX) - ] - - for member in archive_info["members"]: - if member["is_dir"] or member["is_resource_fork"]: - continue - - if PurePath(member["path"]).suffix.lower()[1:] == PROPERTIES_SUFFIX: - member["is_properties_file"] = True - elif f"{member['path']}.{PROPERTIES_SUFFIX}" in properties_files: - member[ - "related_properties_file" - ] = f"{member['path']}.{PROPERTIES_SUFFIX}" - - archive_contents.append(member) - except (unarchiver.LsarCommandError, unarchiver.LsarOutputError): - pass - - size_mb = "{:,.1f}".format(file.size / 1024 / 1024) - dtype = proto.PbDeviceType.Name(file.type) - files.append( - { - "name": file.name, - "size": file.size, - "size_mb": size_mb, - "detected_type": dtype, - "prop": prop, - "archive_contents": archive_contents, - } - ) - - return {"status": result.status, "msg": result.msg, "files": files} - # noinspection PyMethodMayBeStatic def delete_file(self, file_path): """ @@ -892,15 +808,3 @@ class FileCmds: logging.info("stderr: %s", stderr) return {"returncode": proc.returncode, "stdout": stdout, "stderr": stderr} - - # noinspection PyMethodMayBeStatic - @lru_cache(maxsize=32) - def _get_archive_info(self, file_path, **kwargs): - """ - Cached wrapper method to improve performance, e.g. on index screen - """ - try: - return unarchiver.inspect_archive(file_path) - except (unarchiver.LsarCommandError, unarchiver.LsarOutputError) as error: - logging.error(str(error)) - raise diff --git a/python/common/src/piscsi/piscsi_cmds.py b/python/common/src/piscsi/piscsi_cmds.py index 2f7b16fc..408f8b76 100644 --- a/python/common/src/piscsi/piscsi_cmds.py +++ b/python/common/src/piscsi/piscsi_cmds.py @@ -2,10 +2,21 @@ Module for commands sent to the PiSCSI backend service. """ +import logging +from pathlib import PurePath, Path +from functools import lru_cache + import piscsi_interface_pb2 as proto from piscsi.return_codes import ReturnCodes from piscsi.socket_cmds import SocketCmds -import logging + +from piscsi.common_settings import ( + CFG_DIR, + PROPERTIES_SUFFIX, + ARCHIVE_FILE_SUFFIXES, +) + +from util import unarchiver class PiscsiCmds: @@ -24,6 +35,79 @@ class PiscsiCmds: return self.sock_cmd.send_pb_command(command.SerializeToString()) + def list_images(self): + """ + Sends a IMAGE_FILES_INFO command to the server + Returns a (dict) with (bool) status, (str) msg, and (list) of (dict)s files + """ + from piscsi.file_cmds import FileCmds + + self.file_cmd = FileCmds(piscsi=self) + + command = proto.PbCommand() + command.operation = proto.PbOperation.DEFAULT_IMAGE_FILES_INFO + command.params["token"] = self.token + command.params["locale"] = self.locale + + data = self.send_pb_command(command) + result = proto.PbResult() + result.ParseFromString(data) + + server_info = self.get_server_info() + files = [] + for file in result.image_files_info.image_files: + prop_file_path = Path(CFG_DIR) / f"{file.name}.{PROPERTIES_SUFFIX}" + # Add properties meta data for the image, if matching prop file is found + if prop_file_path.exists(): + process = self.file_cmd.read_drive_properties(prop_file_path) + prop = process["conf"] + else: + prop = False + + archive_contents = [] + if PurePath(file.name).suffix.lower()[1:] in ARCHIVE_FILE_SUFFIXES: + try: + archive_info = self._get_archive_info( + f"{server_info['image_dir']}/{file.name}", + _cache_extra_key=file.size, + ) + + properties_files = [ + x["path"] + for x in archive_info["members"] + if x["path"].endswith(PROPERTIES_SUFFIX) + ] + + for member in archive_info["members"]: + if member["is_dir"] or member["is_resource_fork"]: + continue + + if PurePath(member["path"]).suffix.lower()[1:] == PROPERTIES_SUFFIX: + member["is_properties_file"] = True + elif f"{member['path']}.{PROPERTIES_SUFFIX}" in properties_files: + member[ + "related_properties_file" + ] = f"{member['path']}.{PROPERTIES_SUFFIX}" + + archive_contents.append(member) + except (unarchiver.LsarCommandError, unarchiver.LsarOutputError): + pass + + size_mb = "{:,.1f}".format(file.size / 1024 / 1024) + dtype = proto.PbDeviceType.Name(file.type) + files.append( + { + "name": file.name, + "size": file.size, + "size_mb": size_mb, + "detected_type": dtype, + "prop": prop, + "archive_contents": archive_contents, + } + ) + + return {"status": result.status, "msg": result.msg, "files": files} + def get_server_info(self): """ Sends a SERVER_INFO command to the server. @@ -521,3 +605,15 @@ class PiscsiCmds: message += f", device: {formatted_device}" return message + + # noinspection PyMethodMayBeStatic + @lru_cache(maxsize=32) + def _get_archive_info(self, file_path, **kwargs): + """ + Cached wrapper method to improve performance, e.g. on index screen + """ + try: + return unarchiver.inspect_archive(file_path) + except (unarchiver.LsarCommandError, unarchiver.LsarOutputError) as error: + logging.error(str(error)) + raise diff --git a/python/ctrlboard/src/ctrlboard_menu_builder.py b/python/ctrlboard/src/ctrlboard_menu_builder.py index 25075f1d..cfacbc23 100644 --- a/python/ctrlboard/src/ctrlboard_menu_builder.py +++ b/python/ctrlboard/src/ctrlboard_menu_builder.py @@ -142,7 +142,7 @@ class CtrlBoardMenuBuilder(MenuBuilder): def create_images_menu(self, context_object=None): """Creates a sub menu showing all the available images""" menu = Menu(CtrlBoardMenuBuilder.IMAGES_MENU) - images_info = self.file_cmd.list_images() + images_info = self.piscsi_cmd.list_images() menu.add_entry("Return", {"context": self.IMAGES_MENU, "action": self.ACTION_RETURN}) images = images_info["files"] sorted_images = sorted(images, key=lambda d: d["name"]) diff --git a/python/web/src/templates/upload.html b/python/web/src/templates/upload.html index c572469e..a2be4a5d 100644 --- a/python/web/src/templates/upload.html +++ b/python/web/src/templates/upload.html @@ -4,7 +4,6 @@

{{ _("Upload File from Local Computer") }}