From 49a571d26cae771f84c0471408b1a0725ddff4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=81?= Date: Fri, 5 Feb 2021 17:01:00 +0300 Subject: [PATCH] Added 'dconf' format. --- .../templates/format/backgrounds_format.py | 25 ++++-- calculate/templates/format/dconf_format.py | 76 +++++++++++++++++++ calculate/templates/format/patch_format.py | 14 +++- calculate/utils/images.py | 14 +--- tests/templates/format/test_dconf.py | 1 + 5 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 calculate/templates/format/dconf_format.py create mode 100644 tests/templates/format/test_dconf.py diff --git a/calculate/templates/format/backgrounds_format.py b/calculate/templates/format/backgrounds_format.py index f0d2d8a..a4ce64f 100644 --- a/calculate/templates/format/backgrounds_format.py +++ b/calculate/templates/format/backgrounds_format.py @@ -2,8 +2,8 @@ # from ..template_engine import ParametersContainer, Variables from ...variables.datavars import NamespaceNode, VariableNotFoundError +from ...utils.images import ImageMagick, ImageMagickError from ...variables.loader import Datavars -from ...utils.images import ImageMagick from .base_format import Format, FormatError from typing import Union, List, Tuple, NoReturn @@ -57,9 +57,13 @@ class BackgroundsFormat(Format): if not self._check_source(self._source, target_path, self._mirror): return self.changed_files - self._magician = ImageMagick( - chroot=chroot_path if not self._fake_chroot else "/") - source_resolution = self._magician.get_image_resolution(self._source) + try: + self._magician = ImageMagick(chroot=chroot_path + if not self._fake_chroot else "/") + source_resolution = self._magician.get_image_resolution( + self._source) + except ImageMagickError as error: + raise FormatError(f"ImageMagickError: {error}") resolutions_from_var = False resolutions = self._get_resolutions_from_lines(self._lines, @@ -91,8 +95,12 @@ class BackgroundsFormat(Format): self._stretch): continue width, height = resolution - converter(self._source, output_path, height, width, - image_format=images_format) + try: + converter(self._source, output_path, height, width, + image_format=images_format) + except ImageMagickError as error: + raise FormatError(f"ImageMagickError: {error}") + if output_path in self.changed_files: self.changed_files[output_path] = 'M' else: @@ -111,7 +119,10 @@ class BackgroundsFormat(Format): else: images_format = convert else: - images_format = self._magician.get_image_format(self._source) + try: + images_format = self._magician.get_image_format(self._source) + except ImageMagickError as error: + raise FormatError(f"ImageMagickError: {error}") return images_format def _make_output_paths(self, lines: List[str], diff --git a/calculate/templates/format/dconf_format.py b/calculate/templates/format/dconf_format.py new file mode 100644 index 0000000..2cd061a --- /dev/null +++ b/calculate/templates/format/dconf_format.py @@ -0,0 +1,76 @@ +# vim: fileencoding=utf-8 +# +from ..template_engine import ParametersContainer +from .base_format import Format, FormatError +from calculate.utils.files import Process +import os + + +class DConfFormat(Format): + FORMAT = 'dconf' + EXECUTABLE = True + + def __init__(self, template_text: str, + template_path: str, + parameters: ParametersContainer = ParametersContainer(), + **kwargs): + self._dconf_text = template_text + self._init_cmd() + + if parameters.user: + self._user = parameters.user + else: + self._user = "root" + + # Измененные файлы. + self.changed_files = dict() + + # Предупреждения. + self._warnings: list = [] + + def _init_cmd(self): + self._dbus_run_session_cmd = "/usr/bin/dbus-run-session" + if os.path.exists(self._dbus_run_session_cmd): + self._dbus_run_session_cmd = None + self._su_cmd = "/usr/bin/su" + if os.path.exists(self._su_cmd): + self._su_cmd = None + self._dconf_cmd = "/usr/bin/dconf" + if os.path.exists(self._dconf_cmd): + self._dconf_cmd = None + + def execute_format(self, target_path: str, + chroot_path: str = '/') -> dict: + if None in (self._dbus_run_session_cmd, self._su_cmd, self._dconf_cmd): + raise FormatError("the 'dconf' format is not available.") + + if not os.path.exists(os.path.dirname(target_path)): + raise FormatError( + "dconf base directory does not exist: {}".format( + os.path.dirname(target_path))) + if os.path.isdir(target_path): + base_directory = target_path + else: + base_directory = os.path.dirname(target_path) + + dconf_command = f"{0} {1} load {2}".format(self._dbus_run_session_cmd, + self._dconf_cmd, + base_directory) + command = [self._su_cmd, self._user, "-c", dconf_command] + dconf_process = Process(*command) + dconf_process.write(self._dconf_text) + + if dconf_process.success(): + return self.changed_files + else: + error = dconf_process.read_error() + raise FormatError(error) + + return self.changed_files + + def __bool__(self): + return bool(self._patch_text) + + @property + def warnings(self): + return self._warnings diff --git a/calculate/templates/format/patch_format.py b/calculate/templates/format/patch_format.py index c75cc3a..2289039 100644 --- a/calculate/templates/format/patch_format.py +++ b/calculate/templates/format/patch_format.py @@ -1,8 +1,8 @@ # vim: fileencoding=utf-8 # -from .base_format import Format +from .base_format import Format, FormatError from calculate.utils.files import Process -from calculate.templates.format.base_format import FormatError +from typing import NoReturn from os import path @@ -17,15 +17,25 @@ class PatchFormat(Format): self._cwd_path = '/' self._last_level = 0 + self._init_command() + # Измененные файлы. self.changed_files = dict() # Предупреждения. self._warnings: list = [] + def _init_command(self) -> NoReturn: + self._patch_cmd = "/usr/bin/patch" + if not path.exists(self._patch_cmd): + self._patch_cmd = None + def execute_format(self, target_path: str, chroot_path: str = '/') -> dict: '''Метод для запуска работы формата.''' + if self._patch_cmd is None: + raise FormatError("the 'patch' format is not available") + self._cwd_path = target_path if not path.isdir(self._cwd_path): # Если target_path -- путь к файлу, запускаем все процессы из diff --git a/calculate/utils/images.py b/calculate/utils/images.py index 7eaa813..669fef6 100644 --- a/calculate/utils/images.py +++ b/calculate/utils/images.py @@ -44,9 +44,7 @@ class ImageMagick: ) -> Union[None, Tuple[int, int]]: '''Метод для получения разрешения указанного изображения, с помощью команды 'identify -format %w %h '.''' - print(f"SOURCE: {source}") if self.chrooted: - print(f"CHROOT_PATH: {self._chroot_path}") identify = Process(self.chroot_cmd, self._chroot_path, self.bash_cmd, "-c", " ".join([self.identify_cmd, @@ -61,9 +59,9 @@ class ImageMagick: if swidth.isdigit() and sheight.isdigit(): return int(swidth), int(sheight) else: - raise ImageMagickError(f"ERROR: can not parse: '{result}'") + raise ImageMagickError(f"Can not parse: '{result}'") else: - raise ImageMagickError(f"ERROR: {identify.read_error()}") + raise ImageMagickError(identify.read_error()) def convert(self, source: str, target: str, *opts: List[str], image_format: Optional[str] = None) -> bool: @@ -80,15 +78,11 @@ class ImageMagick: self.bash_cmd, "-c", " ".join(command)) else: - print("OPTIONS:") - print(command) convert = Process(*command) if convert.success(): - print("CREATED: {}".format(target)) return True else: - print("ERROR:", convert.read_error()) - return False + raise ImageMagickError(convert.read_error()) def convert_resize_crop_center(self, source: str, target: str, height: int, width: int, @@ -132,4 +126,4 @@ class ImageMagick: image_format = identify.read() return image_format else: - raise ImageMagickError(f"ERROR: {identify.read_error()}") + raise ImageMagickError(f"{identify.read_error()}") diff --git a/tests/templates/format/test_dconf.py b/tests/templates/format/test_dconf.py new file mode 100644 index 0000000..a8b33f1 --- /dev/null +++ b/tests/templates/format/test_dconf.py @@ -0,0 +1 @@ +# TODO Придумать, как тестировать. Пока непонятно.