diff --git a/common/encfstools.py b/common/encfstools.py index c82909437..cc28c320c 100644 --- a/common/encfstools.py +++ b/common/encfstools.py @@ -218,12 +218,8 @@ class EncFS_SSH(EncFS_mount): rsync will then sync the encrypted view on / to the remote path """ def __init__(self, cfg = None, profile_id = None, mode = None, parent = None,*args, **kwargs): - self.config = cfg - if self.config is None: - self.config = config.Config() - self.profile_id = profile_id - if self.profile_id is None: - self.profile_id = self.config.currentProfile() + self.config = cfg or config.Config() + self.profile_id = profile_id or self.config.currentProfile() self.mode = mode if self.mode is None: self.mode = self.config.snapshotsMode(self.profile_id) diff --git a/common/mount.py b/common/mount.py index 357023cc1..b7af736e2 100644 --- a/common/mount.py +++ b/common/mount.py @@ -104,18 +104,18 @@ def postUmountCheck(self): return True """ +import getpass +import json import os import subprocess -import json -import getpass -from zlib import crc32 from time import sleep +from zlib import crc32 import config import logger -import tools import password -from exceptions import MountException, HashCollision +import tools +from exceptions import HashCollision, MountException class Mount(object): @@ -143,14 +143,8 @@ def __init__(self, profile_id = None, tmp_mount = False, parent = None): - self.config = cfg - if self.config is None: - self.config = config.Config() - - self.profile_id = profile_id - if self.profile_id is None: - self.profile_id = self.config.currentProfile() - + self.config = cfg or config.Config() + self.profile_id = profile_id or self.config.currentProfile() self.tmp_mount = tmp_mount self.parent = parent @@ -437,13 +431,9 @@ def __init__(self, self.mountproc = None self.symlink_subfolder = None - self.config = cfg - if self.config is None: - self.config = config.Config() + self.config = cfg or config.Config() - self.profile_id = profile_id - if self.profile_id is None: - self.profile_id = self.config.currentProfile() + self.profile_id = profile_id or self.config.currentProfile() self.tmp_mount = tmp_mount self.hash_id = hash_id diff --git a/common/test/constants.py b/common/test/constants.py new file mode 100644 index 000000000..c3b2449a7 --- /dev/null +++ b/common/test/constants.py @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan +# SPDX-FileCopyrightText: © 2008-2022 Bart de Koning +# SPDX-FileCopyrightText: © 2008-2022 Richard Bailey +# SPDX-FileCopyrightText: © 2008-2022 Germar Reitze +# SPDX-FileCopyrightText: © 2024 Ihor Pryyma +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# This file is part of the program "Back In Time" which is released under GNU +# General Public License v2 (GPLv2). +# See file LICENSE or go to . +""" +Constants that are used in the test files. +""" +import grp +import os +import pwd + +CURRENTUID = os.geteuid() +CURRENTUSER = pwd.getpwuid(CURRENTUID).pw_name +CURRENTGID = os.getegid() +CURRENTGROUP = grp.getgrgid(CURRENTGID).gr_name +CURRENTUID = os.geteuid() +CURRENTGID = os.getegid() diff --git a/common/test/test_applicationinstance.py b/common/test/test_applicationinstance.py index c83ac5385..8af1b67bf 100644 --- a/common/test/test_applicationinstance.py +++ b/common/test/test_applicationinstance.py @@ -15,11 +15,12 @@ # with this program; if not, write to the Free Software Foundation,Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -import subprocess import os import sys +import subprocess from unittest.mock import patch from threading import Thread + from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), "..")) @@ -70,9 +71,10 @@ def _createProcess(self): def _killProcess(self): if self.subproc: - self.subproc.kill() - self.subproc.wait() - self.subproc = None + subproc = self.subproc + subproc.kill() + subproc.wait() + self.subproc = None def test_create_and_remove_pid_file(self): # create pid file diff --git a/common/test/test_config_crontab.py b/common/test/test_config_crontab.py index 9ed4366d0..693a68b72 100644 --- a/common/test/test_config_crontab.py +++ b/common/test/test_config_crontab.py @@ -1,32 +1,27 @@ -# Back In Time -# Copyright (C) 2024 Kosta Vukicevic, Christian Buhtz +# SPDX-FileCopyrightText: © 2024 Christian Buhtz +# SPDX-FileCopyrightText: © 2024 Kosta Vukicevic # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# SPDX-License-Identifier: GPL-2.0-or-later # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation,Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# This file is part of the program "Back In Time" which is released under GNU +# General Public License v2 (GPLv2). +# See file LICENSE or go to . """Tests about Cron-related behavior of the config module. See also test_schedule.py for low-level-Cron-behavior implemented in schedule module.""" -import unittest -import pyfakefs.fake_filesystem_unittest as pyfakefs_ut -import sys +import inspect import os +import sys import tempfile -import inspect +import unittest from pathlib import Path from unittest import mock + +import pyfakefs.fake_filesystem_unittest as pyfakefs_ut + sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + import config @@ -80,6 +75,7 @@ def setUp(self): def _create_config_file(self, parent_path): """Minimal config file""" + # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 diff --git a/common/test/test_lint.py b/common/test/test_lint.py index c537bb3f9..95d9e13ea 100644 --- a/common/test/test_lint.py +++ b/common/test/test_lint.py @@ -106,11 +106,12 @@ def test_with_pylint(self): 'R0201', # no-self-use 'R0202', # no-classmethod-decorator 'R0203', # no-staticmethod-decorator + 'R0801', # duplicate-code # Enable asap. This list is a selection of existing (not all!) # problems currently existing in the BIT code base. Quite easy to fix # because their count is low. - # 'R0801', # duplicate-code + # 'W0237', # arguments-renamed # 'W0221', # arguments-differ # 'W0603', # global-statement ] diff --git a/common/test/test_plugin_usercallback.py b/common/test/test_plugin_usercallback.py index 9e0e54f0f..7213e485d 100644 --- a/common/test/test_plugin_usercallback.py +++ b/common/test/test_plugin_usercallback.py @@ -1,17 +1,18 @@ import sys import inspect -import tempfile -from pathlib import Path -import stat import io import unittest import unittest.mock as mock +import tempfile +import stat from contextlib import redirect_stdout, redirect_stderr from ast import literal_eval +from pathlib import Path # This workaround will become obsolet when migrating to src-layout sys.path.append(str(Path(__file__).parent)) sys.path.append(str(Path(__file__).parent / 'plugins')) + import pluginmanager from config import Config from snapshots import Snapshots @@ -206,6 +207,8 @@ def _create_source_and_destination_folders(cls, parent_path): @classmethod def _create_config_file(cls, parent_path): + """Minimal config file""" + # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 diff --git a/common/test/test_restore.py b/common/test/test_restore.py index 97d1111fa..e66027927 100644 --- a/common/test/test_restore.py +++ b/common/test/test_restore.py @@ -18,20 +18,15 @@ import os import sys import unittest -import pwd -import grp import stat from tempfile import TemporaryDirectory + from test import generic +from test.constants import CURRENTUSER, CURRENTGROUP sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import mount -CURRENTUID = os.geteuid() -CURRENTUSER = pwd.getpwuid(CURRENTUID).pw_name - -CURRENTGID = os.getegid() -CURRENTGROUP = grp.getgrgid(CURRENTGID).gr_name class RestoreTestCase(generic.SnapshotsWithSidTestCase): def setUp(self): diff --git a/common/test/test_snapshots.py b/common/test/test_snapshots.py index 7783567c3..925cfa898 100644 --- a/common/test/test_snapshots.py +++ b/common/test/test_snapshots.py @@ -14,13 +14,11 @@ # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation,Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - import os import sys import pathlib import shutil import stat -import pwd import grp import re import random @@ -30,6 +28,7 @@ from datetime import date, datetime from tempfile import TemporaryDirectory from test import generic +from test.constants import CURRENTUSER, CURRENTGROUP, CURRENTGID, CURRENTUID sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import logger @@ -38,11 +37,6 @@ import tools import mount -CURRENTUID = os.geteuid() -CURRENTUSER = pwd.getpwuid(CURRENTUID).pw_name - -CURRENTGID = os.getegid() -CURRENTGROUP = grp.getgrgid(CURRENTGID).gr_name # all groups the current user is member in GROUPS = [i.gr_name for i in grp.getgrall() if CURRENTUSER in i.gr_mem] diff --git a/common/test/test_tools.py b/common/test/test_tools.py index f9d31321b..87f47edc1 100644 --- a/common/test/test_tools.py +++ b/common/test/test_tools.py @@ -23,13 +23,13 @@ import gzip import stat import signal +from datetime import datetime +from time import sleep from unittest.mock import patch from copy import deepcopy from tempfile import NamedTemporaryFile, TemporaryDirectory -from datetime import datetime -from test import generic -from time import sleep import pyfakefs.fake_filesystem_unittest as pyfakefs_ut +from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import tools @@ -98,7 +98,7 @@ def _kill_process(self): if self.subproc: self.subproc.kill() self.subproc.wait() - self.subproc = None + self.subproc = None def test_sharePath(self): share = tools.sharePath() diff --git a/qt/app.py b/qt/app.py index d2fb9e008..c202f2c92 100644 --- a/qt/app.py +++ b/qt/app.py @@ -98,6 +98,7 @@ import languagedialog import messagebox from aboutdlg import AboutDlg +import qttools class MainWindow(QMainWindow): @@ -878,13 +879,9 @@ def updateProfiles(self): self.comboProfiles.clear() + qttools.update_combo_profiles(self.config, self.comboProfiles, self.config.currentProfile()) profiles = self.config.profilesSortedByName() - for profile_id in profiles: - self.comboProfiles.addProfileID(profile_id) - if profile_id == self.config.currentProfile(): - self.comboProfiles.setCurrentProfileID(profile_id) - self.comboProfilesAction.setVisible(len(profiles) > 1) self.updateProfile() diff --git a/qt/logviewdialog.py b/qt/logviewdialog.py index 117308c84..2cfd0e55e 100644 --- a/qt/logviewdialog.py +++ b/qt/logviewdialog.py @@ -31,6 +31,7 @@ import encfstools import snapshotlog import tools +import qttools class LogViewDialog(QDialog): @@ -187,16 +188,12 @@ def updateProfiles(self): self.comboProfiles.clear() - profiles = self.config.profilesSortedByName() - for profile_id in profiles: - self.comboProfiles.addProfileID(profile_id) - if profile_id == current_profile_id: - self.comboProfiles.setCurrentProfileID(profile_id) + qttools.update_combo_profiles(self.config, self.comboProfiles, current_profile_id) self.enableUpdate = True self.updateLog() - if len(profiles) <= 1: + if len(self.config.profilesSortedByName()) <= 1: self.lblProfile.setVisible(False) self.comboProfiles.setVisible(False) diff --git a/qt/qtsystrayicon.py b/qt/qtsystrayicon.py index 4bcd3a9ec..67f1eb924 100644 --- a/qt/qtsystrayicon.py +++ b/qt/qtsystrayicon.py @@ -201,13 +201,13 @@ def updateInfo(self): self.menuProgress.setVisible(False) def getMenuProgress(self, pg): - d = ( + data = ( ('sent', _('Sent:')), ('speed', _('Speed:')), ('eta', _('ETA:')) ) - for key, txt in d: + for key, txt in data: value = pg.strValue(key, '') if not value: diff --git a/qt/qttools.py b/qt/qttools.py index 9938d461c..f1fdabec0 100644 --- a/qt/qttools.py +++ b/qt/qttools.py @@ -139,6 +139,21 @@ def set_wrapped_tooltip(widget: QWidget, widget.setToolTip('\n'.join(result)) + +def update_combo_profiles(config, combo_profiles, current_profile_id): + """ + Updates the combo box with profiles. + + :param config: Configuration object with access to profile data. + :param combo_profiles: The combo box widget to be updated. + :param current_profile_id: The ID of the current profile to be selected. + """ + profiles = config.profilesSortedByName() + for profile_id in profiles: + combo_profiles.addProfileID(profile_id) + if profile_id == current_profile_id: + combo_profiles.setCurrentProfileID(profile_id) + # |---------------------| # | Misc / Uncatgorized | # |---------------------| diff --git a/qt/settingsdialog.py b/qt/settingsdialog.py index 6d15ec466..f870e2c58 100644 --- a/qt/settingsdialog.py +++ b/qt/settingsdialog.py @@ -67,6 +67,7 @@ import schedulewidget from exceptions import MountException, NoPubKeyLogin, KnownHost from bitbase import URL_ENCRYPT_TRANSITION +import qttools class SshProxyWidget(QWidget): @@ -1192,13 +1193,13 @@ def profileChanged(self, index): if self.disableProfileChanged: return - profile_id = self.comboProfiles.currentProfileID() - if not profile_id: + current_profile_id = self.comboProfiles.currentProfileID() + if not current_profile_id: return - if profile_id != self.config.currentProfile(): + if current_profile_id != self.config.currentProfile(): self.saveProfile() - self.config.setCurrentProfile(profile_id) + self.config.setCurrentProfile(current_profile_id) self.updateProfile() def updateProfiles(self, reloadSettings=True): @@ -1211,11 +1212,7 @@ def updateProfiles(self, reloadSettings=True): self.comboProfiles.clear() - profiles = self.config.profilesSortedByName() - for profile_id in profiles: - self.comboProfiles.addProfileID(profile_id) - if profile_id == current_profile_id: - self.comboProfiles.setCurrentProfileID(profile_id) + qttools.update_combo_profiles(self.config, self.comboProfiles, current_profile_id) self.disableProfileChanged = False diff --git a/qt/test/test_lint.py b/qt/test/test_lint.py index 2e47c8320..f16013c76 100644 --- a/qt/test/test_lint.py +++ b/qt/test/test_lint.py @@ -102,7 +102,7 @@ def test_with_pylint(self): # 'R0201', # no-self-use # 'R0202', # no-classmethod-decorator # 'R0203', # no-staticmethod-decorator - # 'R0801', # duplicate-code + 'R0801', # duplicate-code # 'W0123', # eval-used # 'W0237', # arguments-renamed # 'W0221', # arguments-differ