Fix code with autopep8
This commit is contained in:
		@@ -163,12 +163,14 @@ class Backup:
 | 
				
			|||||||
        """Check if parameters for the backup are valid"""
 | 
					        """Check if parameters for the backup are valid"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.inputs is None or len(self.inputs) == 0:
 | 
					        if self.inputs is None or len(self.inputs) == 0:
 | 
				
			||||||
            logger.info('No existing files or directories specified for backup. Nothing to do')
 | 
					            logger.info(
 | 
				
			||||||
 | 
					                'No existing files or directories specified for backup. Nothing to do')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return 1
 | 
					            return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.output is None:
 | 
					        if self.output is None:
 | 
				
			||||||
            logger.critical('No output path specified. Use -o argument or specify output path in configuration file')
 | 
					            logger.critical(
 | 
				
			||||||
 | 
					                'No output path specified. Use -o argument or specify output path in configuration file')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return 2
 | 
					            return 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -181,7 +183,8 @@ class Backup:
 | 
				
			|||||||
            if self._ssh is None:
 | 
					            if self._ssh is None:
 | 
				
			||||||
                return 5
 | 
					                return 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _, stdout, _ = self._ssh.exec_command(f'if [ -d "{self.output}" ]; then echo "ok"; fi')
 | 
					            _, stdout, _ = self._ssh.exec_command(
 | 
				
			||||||
 | 
					                f'if [ -d "{self.output}" ]; then echo "ok"; fi')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            output = stdout.read().decode('utf-8').strip()
 | 
					            output = stdout.read().decode('utf-8').strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -217,7 +220,8 @@ class Backup:
 | 
				
			|||||||
        if self._remote:
 | 
					        if self._remote:
 | 
				
			||||||
            assert self._ssh is not None
 | 
					            assert self._ssh is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _, stdout, _ = self._ssh.exec_command(f'ls {self.output}/simple_backup')
 | 
					            _, stdout, _ = self._ssh.exec_command(
 | 
				
			||||||
 | 
					                f'ls {self.output}/simple_backup')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            dirs = stdout.read().decode('utf-8').strip().split('\n')
 | 
					            dirs = stdout.read().decode('utf-8').strip().split('\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -234,14 +238,17 @@ class Backup:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                for i in range(n_backup - self.keep):
 | 
					                for i in range(n_backup - self.keep):
 | 
				
			||||||
                    if self.remote_sudo:
 | 
					                    if self.remote_sudo:
 | 
				
			||||||
                        _, _, stderr = self._ssh.exec_command(f'sudo rm -r "{self.output}/simple_backup/{dirs[i]}"')
 | 
					                        _, _, stderr = self._ssh.exec_command(
 | 
				
			||||||
 | 
					                            f'sudo rm -r "{self.output}/simple_backup/{dirs[i]}"')
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        _, _, stderr = self._ssh.exec_command(f'rm -r "{self.output}/simple_backup/{dirs[i]}"')
 | 
					                        _, _, stderr = self._ssh.exec_command(
 | 
				
			||||||
 | 
					                            f'rm -r "{self.output}/simple_backup/{dirs[i]}"')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    err = stderr.read().decode('utf-8').strip().split('\n')[0]
 | 
					                    err = stderr.read().decode('utf-8').strip().split('\n')[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if err != '':
 | 
					                    if err != '':
 | 
				
			||||||
                        logger.error('Error while removing backup %s.', {dirs[i]})
 | 
					                        logger.error(
 | 
				
			||||||
 | 
					                            'Error while removing backup %s.', {dirs[i]})
 | 
				
			||||||
                        logger.error(err)
 | 
					                        logger.error(err)
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        count += 1
 | 
					                        count += 1
 | 
				
			||||||
@@ -267,9 +274,11 @@ class Backup:
 | 
				
			|||||||
                        rmtree(f'{self.output}/simple_backup/{dirs[i]}')
 | 
					                        rmtree(f'{self.output}/simple_backup/{dirs[i]}')
 | 
				
			||||||
                        count += 1
 | 
					                        count += 1
 | 
				
			||||||
                    except FileNotFoundError:
 | 
					                    except FileNotFoundError:
 | 
				
			||||||
                        logger.error('Error while removing backup %s. Directory not found', dirs[i])
 | 
					                        logger.error(
 | 
				
			||||||
 | 
					                            'Error while removing backup %s. Directory not found', dirs[i])
 | 
				
			||||||
                    except PermissionError:
 | 
					                    except PermissionError:
 | 
				
			||||||
                        logger.error('Error while removing backup %s. Permission denied', dirs[i])
 | 
					                        logger.error(
 | 
				
			||||||
 | 
					                            'Error while removing backup %s. Permission denied', dirs[i])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if count == 1:
 | 
					        if count == 1:
 | 
				
			||||||
            logger.info('Removed %d backup', count)
 | 
					            logger.info('Removed %d backup', count)
 | 
				
			||||||
@@ -284,7 +293,8 @@ class Backup:
 | 
				
			|||||||
                logger.critical('SSH connection to server failed')
 | 
					                logger.critical('SSH connection to server failed')
 | 
				
			||||||
                sys.exit(5)
 | 
					                sys.exit(5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _, stdout, _ = self._ssh.exec_command(f'find {self.output}/simple_backup/ -mindepth 1 -maxdepth 1 -type d | sort')
 | 
					            _, stdout, _ = self._ssh.exec_command(
 | 
				
			||||||
 | 
					                f'find {self.output}/simple_backup/ -mindepth 1 -maxdepth 1 -type d | sort')
 | 
				
			||||||
            output = stdout.read().decode('utf-8').strip().split('\n')
 | 
					            output = stdout.read().decode('utf-8').strip().split('\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if output[-1] != '':
 | 
					            if output[-1] != '':
 | 
				
			||||||
@@ -293,13 +303,15 @@ class Backup:
 | 
				
			|||||||
                logger.info('No previous backups available')
 | 
					                logger.info('No previous backups available')
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                dirs = sorted([f.path for f in os.scandir(f'{self.output}/simple_backup') if f.is_dir(follow_symlinks=False)])
 | 
					                dirs = sorted([f.path for f in os.scandir(
 | 
				
			||||||
 | 
					                    f'{self.output}/simple_backup') if f.is_dir(follow_symlinks=False)])
 | 
				
			||||||
            except FileNotFoundError:
 | 
					            except FileNotFoundError:
 | 
				
			||||||
                logger.info('No previous backups available')
 | 
					                logger.info('No previous backups available')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
            except PermissionError:
 | 
					            except PermissionError:
 | 
				
			||||||
                logger.critical('Cannot access the backup directory. Permission denied')
 | 
					                logger.critical(
 | 
				
			||||||
 | 
					                    'Cannot access the backup directory. Permission denied')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    _notify('Backup failed (check log for details)')
 | 
					                    _notify('Backup failed (check log for details)')
 | 
				
			||||||
@@ -333,7 +345,8 @@ class Backup:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            return ssh
 | 
					            return ssh
 | 
				
			||||||
        except UserWarning:
 | 
					        except UserWarning:
 | 
				
			||||||
            k = input(f'Unknown key for host {self.ssh_host}. Continue anyway? (Y/N) ')
 | 
					            k = input(
 | 
				
			||||||
 | 
					                f'Unknown key for host {self.ssh_host}. Continue anyway? (Y/N) ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if k[0].upper() == 'Y':
 | 
					            if k[0].upper() == 'Y':
 | 
				
			||||||
                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 | 
					                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 | 
				
			||||||
@@ -356,8 +369,10 @@ class Backup:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if self.ssh_keyfile is None:
 | 
					        if self.ssh_keyfile is None:
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                password = getpass(f'{self.ssh_user}@{self.ssh_host}\'s password: ')
 | 
					                password = getpass(
 | 
				
			||||||
                ssh.connect(self.ssh_host, username=self.ssh_user, password=password)
 | 
					                    f'{self.ssh_user}@{self.ssh_host}\'s password: ')
 | 
				
			||||||
 | 
					                ssh.connect(self.ssh_host, username=self.ssh_user,
 | 
				
			||||||
 | 
					                            password=password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                self._password_auth = True
 | 
					                self._password_auth = True
 | 
				
			||||||
                os.environ['SSHPASS'] = password
 | 
					                os.environ['SSHPASS'] = password
 | 
				
			||||||
@@ -379,7 +394,8 @@ class Backup:
 | 
				
			|||||||
        try:
 | 
					        try:
 | 
				
			||||||
            pkey = RSAKey.from_private_key_file(self.ssh_keyfile)
 | 
					            pkey = RSAKey.from_private_key_file(self.ssh_keyfile)
 | 
				
			||||||
        except paramiko.PasswordRequiredException:
 | 
					        except paramiko.PasswordRequiredException:
 | 
				
			||||||
            password = getpass(f'Enter passwphrase for key \'{self.ssh_keyfile}\': ')
 | 
					            password = getpass(
 | 
				
			||||||
 | 
					                f'Enter passwphrase for key \'{self.ssh_keyfile}\': ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                pkey = RSAKey.from_private_key_file(self.ssh_keyfile, password)
 | 
					                pkey = RSAKey.from_private_key_file(self.ssh_keyfile, password)
 | 
				
			||||||
@@ -391,7 +407,8 @@ class Backup:
 | 
				
			|||||||
                pkey = Ed25519Key.from_private_key_file(self.ssh_keyfile)
 | 
					                pkey = Ed25519Key.from_private_key_file(self.ssh_keyfile)
 | 
				
			||||||
            except paramiko.PasswordRequiredException:
 | 
					            except paramiko.PasswordRequiredException:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    pkey = Ed25519Key.from_private_key_file(self.ssh_keyfile, password)
 | 
					                    pkey = Ed25519Key.from_private_key_file(
 | 
				
			||||||
 | 
					                        self.ssh_keyfile, password)
 | 
				
			||||||
                except paramiko.SSHException:
 | 
					                except paramiko.SSHException:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -400,7 +417,8 @@ class Backup:
 | 
				
			|||||||
                pkey = ECDSAKey.from_private_key_file(self.ssh_keyfile)
 | 
					                pkey = ECDSAKey.from_private_key_file(self.ssh_keyfile)
 | 
				
			||||||
            except paramiko.PasswordRequiredException:
 | 
					            except paramiko.PasswordRequiredException:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    pkey = ECDSAKey.from_private_key_file(self.ssh_keyfile, password)
 | 
					                    pkey = ECDSAKey.from_private_key_file(
 | 
				
			||||||
 | 
					                        self.ssh_keyfile, password)
 | 
				
			||||||
                except paramiko.SSHException:
 | 
					                except paramiko.SSHException:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -409,7 +427,8 @@ class Backup:
 | 
				
			|||||||
                pkey = DSSKey.from_private_key_file(self.ssh_keyfile)
 | 
					                pkey = DSSKey.from_private_key_file(self.ssh_keyfile)
 | 
				
			||||||
            except paramiko.PasswordRequiredException:
 | 
					            except paramiko.PasswordRequiredException:
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    pkey = DSSKey.from_private_key_file(self.ssh_keyfile, password)
 | 
					                    pkey = DSSKey.from_private_key_file(
 | 
				
			||||||
 | 
					                        self.ssh_keyfile, password)
 | 
				
			||||||
                except paramiko.SSHException:
 | 
					                except paramiko.SSHException:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -425,31 +444,44 @@ class Backup:
 | 
				
			|||||||
    def _returncode_log(self, returncode: int) -> None:
 | 
					    def _returncode_log(self, returncode: int) -> None:
 | 
				
			||||||
        match returncode:
 | 
					        match returncode:
 | 
				
			||||||
            case 2:
 | 
					            case 2:
 | 
				
			||||||
                logger.error('Rsync error (return code 2) - Protocol incompatibility')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 2) - Protocol incompatibility')
 | 
				
			||||||
            case 3:
 | 
					            case 3:
 | 
				
			||||||
                logger.error('Rsync error (return code 3) - Errors selecting input/output files, dirs')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 3) - Errors selecting input/output files, dirs')
 | 
				
			||||||
            case 4:
 | 
					            case 4:
 | 
				
			||||||
                logger.error('Rsync error (return code 4) - Requested action not supported')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 4) - Requested action not supported')
 | 
				
			||||||
            case 5:
 | 
					            case 5:
 | 
				
			||||||
                logger.error('Rsync error (return code 5) - Error starting client-server protocol')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 5) - Error starting client-server protocol')
 | 
				
			||||||
            case 10:
 | 
					            case 10:
 | 
				
			||||||
                logger.error('Rsync error (return code 10) - Error in socket I/O')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 10) - Error in socket I/O')
 | 
				
			||||||
            case 11:
 | 
					            case 11:
 | 
				
			||||||
                logger.error('Rsync error (return code 11) - Error in file I/O')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 11) - Error in file I/O')
 | 
				
			||||||
            case 12:
 | 
					            case 12:
 | 
				
			||||||
                logger.error('Rsync error (return code 12) - Error in rsync protocol data stream')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 12) - Error in rsync protocol data stream')
 | 
				
			||||||
            case 22:
 | 
					            case 22:
 | 
				
			||||||
                logger.error('Rsync error (return code 22) - Error allocating core memory buffers')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 22) - Error allocating core memory buffers')
 | 
				
			||||||
            case 23:
 | 
					            case 23:
 | 
				
			||||||
                logger.warning('Rsync error (return code 23) - Partial transfer due to error')
 | 
					                logger.warning(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 23) - Partial transfer due to error')
 | 
				
			||||||
            case 24:
 | 
					            case 24:
 | 
				
			||||||
                logger.warning('Rsync error (return code 24) - Partial transfer due to vanished source files')
 | 
					                logger.warning(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 24) - Partial transfer due to vanished source files')
 | 
				
			||||||
            case 30:
 | 
					            case 30:
 | 
				
			||||||
                logger.error('Rsync error (return code 30) - Timeout in data send/receive')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 30) - Timeout in data send/receive')
 | 
				
			||||||
            case 35:
 | 
					            case 35:
 | 
				
			||||||
                logger.error('Rsync error (return code 35) - Timeout waiting for daemon connection')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code 35) - Timeout waiting for daemon connection')
 | 
				
			||||||
            case _:
 | 
					            case _:
 | 
				
			||||||
                logger.error('Rsync error (return code %d) - Check rsync(1) for details', returncode)
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Rsync error (return code %d) - Check rsync(1) for details', returncode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Function to read configuration file
 | 
					    # Function to read configuration file
 | 
				
			||||||
    @timing
 | 
					    @timing
 | 
				
			||||||
@@ -479,7 +511,8 @@ class Backup:
 | 
				
			|||||||
                    count += 1
 | 
					                    count += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if count == 0:
 | 
					        if count == 0:
 | 
				
			||||||
            logger.info('No existing files or directories specified for backup. Nothing to do')
 | 
					            logger.info(
 | 
				
			||||||
 | 
					                'No existing files or directories specified for backup. Nothing to do')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                _notify('Backup finished. No files copied')
 | 
					                _notify('Backup finished. No files copied')
 | 
				
			||||||
@@ -503,10 +536,10 @@ class Backup:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if self._last_backup == '':
 | 
					        if self._last_backup == '':
 | 
				
			||||||
            rsync = f'/usr/bin/rsync {self.options} --exclude-from={self._exclude_path} ' +\
 | 
					            rsync = f'/usr/bin/rsync {self.options} --exclude-from={self._exclude_path} ' +\
 | 
				
			||||||
                    f'--files-from={self._inputs_path} / "{self._server}{self._output_dir}"'
 | 
					                f'--files-from={self._inputs_path} / "{self._server}{self._output_dir}"'
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            rsync = f'/usr/bin/rsync {self.options} --link-dest="{self._last_backup}" --exclude-from=' +\
 | 
					            rsync = f'/usr/bin/rsync {self.options} --link-dest="{self._last_backup}" --exclude-from=' +\
 | 
				
			||||||
                    f'{self._exclude_path} --files-from={self._inputs_path} / "{self._server}{self._output_dir}"'
 | 
					                f'{self._exclude_path} --files-from={self._inputs_path} / "{self._server}{self._output_dir}"'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        euid = os.geteuid()
 | 
					        euid = os.geteuid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -559,7 +592,8 @@ class Backup:
 | 
				
			|||||||
        if self._remote:
 | 
					        if self._remote:
 | 
				
			||||||
            assert self._ssh is not None
 | 
					            assert self._ssh is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            _, stdout, _ = self._ssh.exec_command(f'if [ -d "{self._output_dir}" ]; then echo "ok"; fi')
 | 
					            _, stdout, _ = self._ssh.exec_command(
 | 
				
			||||||
 | 
					                f'if [ -d "{self._output_dir}" ]; then echo "ok"; fi')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            output = stdout.read().decode('utf-8').strip()
 | 
					            output = stdout.read().decode('utf-8').strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -582,10 +616,12 @@ class Backup:
 | 
				
			|||||||
                self._ssh.close()
 | 
					                self._ssh.close()
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            if returncode != 0:
 | 
					            if returncode != 0:
 | 
				
			||||||
                logger.error('Some errors occurred while performing the backup')
 | 
					                logger.error(
 | 
				
			||||||
 | 
					                    'Some errors occurred while performing the backup')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    _notify('Some errors occurred while performing the backup. Check log for details')
 | 
					                    _notify(
 | 
				
			||||||
 | 
					                        'Some errors occurred while performing the backup. Check log for details')
 | 
				
			||||||
                except NameError:
 | 
					                except NameError:
 | 
				
			||||||
                    pass
 | 
					                    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -616,26 +652,39 @@ def _parse_arguments() -> argparse.Namespace:
 | 
				
			|||||||
                                     epilog='See simple_backup(1) manpage for full documentation',
 | 
					                                     epilog='See simple_backup(1) manpage for full documentation',
 | 
				
			||||||
                                     formatter_class=MyFormatter)
 | 
					                                     formatter_class=MyFormatter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parser.add_argument('-v', '--verbose', action='store_true', help='More verbose output')
 | 
					    parser.add_argument('-v', '--verbose', action='store_true',
 | 
				
			||||||
 | 
					                        help='More verbose output')
 | 
				
			||||||
    parser.add_argument('-c', '--config', default=f'{homedir}/.config/simple_backup/simple_backup.conf',
 | 
					    parser.add_argument('-c', '--config', default=f'{homedir}/.config/simple_backup/simple_backup.conf',
 | 
				
			||||||
                        help='Specify location of configuration file')
 | 
					                        help='Specify location of configuration file')
 | 
				
			||||||
    parser.add_argument('-i', '--inputs', nargs='+', help='Paths/files to backup')
 | 
					    parser.add_argument('-i', '--inputs', nargs='+',
 | 
				
			||||||
    parser.add_argument('-o', '--output', help='Output directory for the backup')
 | 
					                        help='Paths/files to backup')
 | 
				
			||||||
    parser.add_argument('-e', '--exclude', nargs='+', help='Files/directories/patterns to exclude from the backup')
 | 
					    parser.add_argument(
 | 
				
			||||||
    parser.add_argument('-k', '--keep', type=int, help='Number of old backups to keep')
 | 
					        '-o', '--output', help='Output directory for the backup')
 | 
				
			||||||
    parser.add_argument('-u', '--user', help='Explicitly specify the user running the backup')
 | 
					    parser.add_argument('-e', '--exclude', nargs='+',
 | 
				
			||||||
    parser.add_argument('-s', '--checksum', action='store_true', help='Use checksum rsync option to compare files')
 | 
					                        help='Files/directories/patterns to exclude from the backup')
 | 
				
			||||||
    parser.add_argument('--ssh-host', help='Server hostname (for remote backup)')
 | 
					    parser.add_argument('-k', '--keep', type=int,
 | 
				
			||||||
    parser.add_argument('--ssh-user', help='Username to connect to server (for remote backup)')
 | 
					                        help='Number of old backups to keep')
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '-u', '--user', help='Explicitly specify the user running the backup')
 | 
				
			||||||
 | 
					    parser.add_argument('-s', '--checksum', action='store_true',
 | 
				
			||||||
 | 
					                        help='Use checksum rsync option to compare files')
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '--ssh-host', help='Server hostname (for remote backup)')
 | 
				
			||||||
 | 
					    parser.add_argument(
 | 
				
			||||||
 | 
					        '--ssh-user', help='Username to connect to server (for remote backup)')
 | 
				
			||||||
    parser.add_argument('--keyfile', help='SSH key location')
 | 
					    parser.add_argument('--keyfile', help='SSH key location')
 | 
				
			||||||
    parser.add_argument('-z', '--compress', action='store_true', help='Compress data during the transfer')
 | 
					    parser.add_argument('-z', '--compress', action='store_true',
 | 
				
			||||||
 | 
					                        help='Compress data during the transfer')
 | 
				
			||||||
    parser.add_argument('--remove-before-backup', action='store_true',
 | 
					    parser.add_argument('--remove-before-backup', action='store_true',
 | 
				
			||||||
                        help='Remove old backups before executing the backup, instead of after')
 | 
					                        help='Remove old backups before executing the backup, instead of after')
 | 
				
			||||||
    parser.add_argument('--no-syslog', action='store_true', help='Disable systemd journal logging')
 | 
					    parser.add_argument('--no-syslog', action='store_true',
 | 
				
			||||||
 | 
					                        help='Disable systemd journal logging')
 | 
				
			||||||
    parser.add_argument('--rsync-options', nargs='+',
 | 
					    parser.add_argument('--rsync-options', nargs='+',
 | 
				
			||||||
                        choices=['a', 'l', 'p', 't', 'g', 'o', 'c', 'h', 's', 'D', 'H', 'X'],
 | 
					                        choices=['a', 'l', 'p', 't', 'g', 'o',
 | 
				
			||||||
 | 
					                                 'c', 'h', 's', 'D', 'H', 'X'],
 | 
				
			||||||
                        help='Specify options for rsync')
 | 
					                        help='Specify options for rsync')
 | 
				
			||||||
    parser.add_argument('--remote-sudo', action='store_true', help='Run rsync on remote server with sudo if allowed')
 | 
					    parser.add_argument('--remote-sudo', action='store_true',
 | 
				
			||||||
 | 
					                        help='Run rsync on remote server with sudo if allowed')
 | 
				
			||||||
    parser.add_argument('--numeric-ids', action='store_true',
 | 
					    parser.add_argument('--numeric-ids', action='store_true',
 | 
				
			||||||
                        help='Use rsync \'--numeric-ids\' option (don\'t map uid/gid values by name)')
 | 
					                        help='Use rsync \'--numeric-ids\' option (don\'t map uid/gid values by name)')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -660,7 +709,8 @@ def _expand_inputs(inputs, user: Optional[str] = None):
 | 
				
			|||||||
                logger.warning('Cannot expand \'~\'. No user specified')
 | 
					                logger.warning('Cannot expand \'~\'. No user specified')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if len(i_ex) == 0:
 | 
					        if len(i_ex) == 0:
 | 
				
			||||||
            logger.warning('No file or directory matching input %s. Skipping...', i)
 | 
					            logger.warning(
 | 
				
			||||||
 | 
					                'No file or directory matching input %s. Skipping...', i)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            expanded_inputs.extend(i_ex)
 | 
					            expanded_inputs.extend(i_ex)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -682,7 +732,8 @@ def _read_config(config_file, user: Optional[str] = None):
 | 
				
			|||||||
        if user is not None:
 | 
					        if user is not None:
 | 
				
			||||||
            logger.warning('Config file %s does not exist', config_file)
 | 
					            logger.warning('Config file %s does not exist', config_file)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            logger.warning('User not specified. Can\'t read configuration file')
 | 
					            logger.warning(
 | 
				
			||||||
 | 
					                'User not specified. Can\'t read configuration file')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return config_args
 | 
					        return config_args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -776,7 +827,8 @@ def _notify(text: str) -> None:
 | 
				
			|||||||
    os.seteuid(int(uid))
 | 
					    os.seteuid(int(uid))
 | 
				
			||||||
    os.environ['DBUS_SESSION_BUS_ADDRESS'] = f'unix:path=/run/user/{uid}/bus'
 | 
					    os.environ['DBUS_SESSION_BUS_ADDRESS'] = f'unix:path=/run/user/{uid}/bus'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    obj = dbus.SessionBus().get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications')
 | 
					    obj = dbus.SessionBus().get_object('org.freedesktop.Notifications',
 | 
				
			||||||
 | 
					                                       '/org/freedesktop/Notifications')
 | 
				
			||||||
    obj = dbus.Interface(obj, 'org.freedesktop.Notifications')
 | 
					    obj = dbus.Interface(obj, 'org.freedesktop.Notifications')
 | 
				
			||||||
    obj.Notify('', 0, '', 'simple_backup', text, [], {'urgency': 1}, 10000)
 | 
					    obj.Notify('', 0, '', 'simple_backup', text, [], {'urgency': 1}, 10000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -800,7 +852,8 @@ def simple_backup() -> int:
 | 
				
			|||||||
            if user is not None:
 | 
					            if user is not None:
 | 
				
			||||||
                homedir = os.path.expanduser(f'~{user}')
 | 
					                homedir = os.path.expanduser(f'~{user}')
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                logger.warning('Failed to detect user. You can use -u/--user parameter to manually specify it')
 | 
					                logger.warning(
 | 
				
			||||||
 | 
					                    'Failed to detect user. You can use -u/--user parameter to manually specify it')
 | 
				
			||||||
                homedir = None
 | 
					                homedir = None
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            user = os.getenv('USER')
 | 
					            user = os.getenv('USER')
 | 
				
			||||||
@@ -832,7 +885,8 @@ def simple_backup() -> int:
 | 
				
			|||||||
    remote_sudo = args.remote_sudo or config_args['remote_sudo']
 | 
					    remote_sudo = args.remote_sudo or config_args['remote_sudo']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if args.rsync_options is None:
 | 
					    if args.rsync_options is None:
 | 
				
			||||||
        rsync_options = ['-a', '-r', '-v', '-h', '-H', '-X', '-s', '--ignore-missing-args', '--mkpath']
 | 
					        rsync_options = ['-a', '-r', '-v', '-h', '-H',
 | 
				
			||||||
 | 
					                         '-X', '-s', '--ignore-missing-args', '--mkpath']
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        rsync_options = ['-r', '-v']
 | 
					        rsync_options = ['-r', '-v']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user