diff --git a/actions/auth-pubtkt b/actions/auth-pubtkt index c24492315..a014eced2 100755 --- a/actions/auth-pubtkt +++ b/actions/auth-pubtkt @@ -109,8 +109,9 @@ def subcommand_generate_ticket(arguments): pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, fil.read().encode()) valid_until = minutes_from_now(12 * 60) grace_period = minutes_from_now(11 * 60) - print(create_ticket(pkey, uid, valid_until, tokens=tokens, - graceperiod=grace_period)) + print( + create_ticket(pkey, uid, valid_until, tokens=tokens, + graceperiod=grace_period)) def minutes_from_now(minutes): @@ -120,8 +121,8 @@ def minutes_from_now(minutes): def seconds_from_now(seconds): """Return a timestamp at the given number of seconds from now.""" - return ( - datetime.datetime.now() + datetime.timedelta(0, seconds)).timestamp() + return (datetime.datetime.now() + + datetime.timedelta(0, seconds)).timestamp() def main(): diff --git a/actions/config b/actions/config index ae2fa44a9..0aba395b2 100755 --- a/actions/config +++ b/actions/config @@ -66,8 +66,8 @@ def subcommand_reset_home_page(_): config_file = FREEDOMBOX_APACHE_CONFIG default_path = 'plinth' - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') aug.set('/augeas/load/Httpd/incl[last() + 1]', config_file) aug.load() diff --git a/actions/diaspora b/actions/diaspora index 0a915c9b2..eb435a5f2 100755 --- a/actions/diaspora +++ b/actions/diaspora @@ -72,8 +72,8 @@ def set_domain_name(domain_name): # {'url': domain_name}) # Manually changing the domain name in the conf files. conf_file = '/etc/diaspora.conf' - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # lens for shell-script config file aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') diff --git a/actions/firewall b/actions/firewall index 0fced7220..a7d00b85d 100755 --- a/actions/firewall +++ b/actions/firewall @@ -62,8 +62,9 @@ def parse_arguments(): # Add a service add_service = subparsers.add_parser('add-service', help='Add a service') add_service.add_argument('service', help='Name of the service to add') - add_service.add_argument( - '--zone', help='Zone to which service is to be added', required=True) + add_service.add_argument('--zone', + help='Zone to which service is to be added', + required=True) # Remove a service status remove_service = subparsers.add_parser('remove-service', @@ -111,8 +112,8 @@ def _flush_iptables_rules(): def set_firewall_backend(backend): """Set FirewallBackend attribute to the specified string.""" conf_file = '/etc/firewalld/firewalld.conf' - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # lens for shell-script config file aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') diff --git a/actions/gitweb b/actions/gitweb index 7d55d5995..237bac125 100755 --- a/actions/gitweb +++ b/actions/gitweb @@ -38,7 +38,6 @@ logger = logging.getLogger(__name__) class ValidateRepoName(argparse.Action): """Validate a repository name and add .git extension if necessary.""" - def __call__(self, parser, namespace, values, option_string=None): RepositoryValidator()(values) if not values.endswith('.git'): @@ -48,7 +47,6 @@ class ValidateRepoName(argparse.Action): class ValidateRepoUrl(argparse.Action): """Validate a repository URL.""" - def __call__(self, parser, namespace, values, option_string=None): RepositoryValidator(input_should_be='url')(values) setattr(namespace, self.dest, values) @@ -359,8 +357,9 @@ def subcommand_repo_info(arguments): print( json.dumps( - dict(name=arguments.name[:-4], description=_get_repo_description( - arguments.name), owner=_get_repo_owner(arguments.name), + dict(name=arguments.name[:-4], + description=_get_repo_description(arguments.name), + owner=_get_repo_owner(arguments.name), access=_get_access_status(arguments.name)))) diff --git a/actions/mediawiki b/actions/mediawiki index fe2306bf1..4f0e45a0c 100755 --- a/actions/mediawiki +++ b/actions/mediawiki @@ -48,8 +48,8 @@ def parse_arguments(): help_private_mode = 'Enable/Disable/Status private mode.' private_mode = subparsers.add_parser('private-mode', help=help_private_mode) - private_mode.add_argument('command', choices=('enable', 'disable', - 'status'), + private_mode.add_argument('command', + choices=('enable', 'disable', 'status'), help=help_private_mode) change_password = subparsers.add_parser('change-password', diff --git a/actions/minetest b/actions/minetest index b7db3a51b..3e3f52146 100755 --- a/actions/minetest +++ b/actions/minetest @@ -15,7 +15,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Configuration helper for Minetest server. """ @@ -25,7 +24,6 @@ import augeas from plinth import action_utils - CONFIG_FILE = '/etc/minetest/minetest.conf' AUG_PATH = '/files' + CONFIG_FILE + '/.anon' diff --git a/actions/monkeysphere b/actions/monkeysphere index c09c50514..badaab5c3 100755 --- a/actions/monkeysphere +++ b/actions/monkeysphere @@ -150,9 +150,8 @@ def get_monkeysphere_keys(key_id=None): """Return the list of keys imported into monkeysphere.""" try: key_ids = [] if not key_id else [key_id] - output = subprocess.check_output( - ['monkeysphere-host', 'show-keys'] + key_ids, - stderr=subprocess.DEVNULL) + output = subprocess.check_output(['monkeysphere-host', 'show-keys'] + + key_ids, stderr=subprocess.DEVNULL) except subprocess.CalledProcessError: # no keys available return {} @@ -288,9 +287,10 @@ def subcommand_host_publish_key(arguments): # setting TMPDIR as workaround for Debian bug #656750 proc = subprocess.Popen( ['monkeysphere-host', 'publish-keys'] + arguments.key_ids, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=dict( - os.environ, TMPDIR='/var/lib/monkeysphere/authentication/tmp/', - MONKEYSPHERE_PROMPT='false')) + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=dict(os.environ, + TMPDIR='/var/lib/monkeysphere/authentication/tmp/', + MONKEYSPHERE_PROMPT='false')) output, error = proc.communicate() output, error = output.decode(), error.decode() if proc.returncode != 0: diff --git a/actions/openvpn b/actions/openvpn index 720d5cc8d..ccac2d084 100755 --- a/actions/openvpn +++ b/actions/openvpn @@ -177,8 +177,8 @@ def subcommand_upgrade(_): 'renewed/private_by_serial', 'renewed/reqs_by_serial' ] for dir_name in directories_to_create: - os.makedirs( - os.path.join(pki_dir, dir_name), mode=0o700, exist_ok=True) + os.makedirs(os.path.join(pki_dir, dir_name), mode=0o700, + exist_ok=True) def _move_by_file_extension(file_extension, directory, excluded=None): excluded = excluded or [] @@ -217,7 +217,6 @@ def _write_server_config(): def _setup_firewall(): """Add TUN device to internal zone in firewalld.""" - def _configure_interface(interface, operation): """Add or remove an interface into internal zone.""" command = [ @@ -299,9 +298,10 @@ def subcommand_get_profile(arguments): user_key_string = _read_file(user_key) ca_string = _read_file(CA_CERTIFICATE_PATH) - profile = CLIENT_CONFIGURATION.format( - ca=ca_string, cert=user_certificate_string, key=user_key_string, - remote=remote_server) + profile = CLIENT_CONFIGURATION.format(ca=ca_string, + cert=user_certificate_string, + key=user_key_string, + remote=remote_server) print(profile) @@ -326,8 +326,8 @@ def _is_non_empty_file(filepath): def load_augeas(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # shell-script config file lens aug.set('/augeas/load/Simplevars/lens', 'Simplevars.lns') diff --git a/actions/packages b/actions/packages index 887e70162..9855d4085 100755 --- a/actions/packages +++ b/actions/packages @@ -349,8 +349,9 @@ def _download_packages(packages): return downloaded_files -def _get_conffile_hashes_from_downloaded_files( - packages, downloaded_files, status_hashes, mismatched_hashes): +def _get_conffile_hashes_from_downloaded_files(packages, downloaded_files, + status_hashes, + mismatched_hashes): """Retrieve the conffile hashes from downloaded .deb files.""" new_hashes = defaultdict(dict) new_versions = defaultdict(lambda: None) @@ -369,8 +370,9 @@ def _get_conffile_hashes_from_downloaded_files( return new_hashes, new_versions -def _get_conffile_hashes_from_downloaded_file( - packages, downloaded_file, status_hashes, mismatched_hashes): +def _get_conffile_hashes_from_downloaded_file(packages, downloaded_file, + status_hashes, + mismatched_hashes): """Retrieve the conffile hashes from a single downloaded .deb file.""" deb_file = apt_inst.DebFile(downloaded_file) diff --git a/actions/pagekite b/actions/pagekite index 36d095699..19477a9ca 100755 --- a/actions/pagekite +++ b/actions/pagekite @@ -31,13 +31,18 @@ from plinth.modules.pagekite import utils aug = None PATHS = { - 'service_on': os.path.join(utils.CONF_PATH, '*', 'service_on', '*'), - 'kitename': os.path.join(utils.CONF_PATH, '10_account.rc', 'kitename'), - 'kitesecret': os.path.join(utils.CONF_PATH, '10_account.rc', 'kitesecret'), - 'abort_not_configured': os.path.join(utils.CONF_PATH, '10_account.rc', - 'abort_not_configured'), - 'defaults': os.path.join(utils.CONF_PATH, '20_frontends.rc', 'defaults'), - 'frontend': os.path.join(utils.CONF_PATH, '20_frontends.rc', 'frontend'), + 'service_on': + os.path.join(utils.CONF_PATH, '*', 'service_on', '*'), + 'kitename': + os.path.join(utils.CONF_PATH, '10_account.rc', 'kitename'), + 'kitesecret': + os.path.join(utils.CONF_PATH, '10_account.rc', 'kitesecret'), + 'abort_not_configured': + os.path.join(utils.CONF_PATH, '10_account.rc', 'abort_not_configured'), + 'defaults': + os.path.join(utils.CONF_PATH, '20_frontends.rc', 'defaults'), + 'frontend': + os.path.join(utils.CONF_PATH, '20_frontends.rc', 'frontend'), } @@ -50,9 +55,9 @@ def parse_arguments(): subparsers.add_parser('start-and-enable', help='Enable PageKite service') subparsers.add_parser('stop-and-disable', help='Disable PageKite service') subparsers.add_parser('restart', help='Restart PageKite service') - subparsers.add_parser('is-disabled', - help=('Whether PageKite is disabled in the file ' - '/etc/pagekite.d/10_accounts.rc')) + subparsers.add_parser( + 'is-disabled', help=('Whether PageKite is disabled in the file ' + '/etc/pagekite.d/10_accounts.rc')) # Frontend subparsers.add_parser('get-frontend', help='Get pagekite frontend') diff --git a/actions/power b/actions/power index 6229b594a..58992dc68 100755 --- a/actions/power +++ b/actions/power @@ -15,7 +15,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Configuration helper for power controls. """ diff --git a/actions/radicale b/actions/radicale index 94864f9c9..7e5c4f53d 100755 --- a/actions/radicale +++ b/actions/radicale @@ -132,8 +132,8 @@ def subcommand_fix_collections(_): def load_augeas(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # shell-script config file lens aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') diff --git a/actions/searx b/actions/searx index 8367b061c..d08f314b5 100755 --- a/actions/searx +++ b/actions/searx @@ -81,8 +81,8 @@ def _update_uwsgi_configuration(): uwsgi 2.0.15-debian crashes when trying to autoload. """ - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/inifile/lens', 'Puppet.lns') aug.set('/augeas/load/inifile/incl[last() + 1]', UWSGI_FILE) aug.load() diff --git a/actions/shadowsocks b/actions/shadowsocks index 670e09ca3..0e5dc1048 100755 --- a/actions/shadowsocks +++ b/actions/shadowsocks @@ -35,12 +35,11 @@ def parse_arguments(): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - subparsers.add_parser('setup', - help='Perform initial setup steps') - subparsers.add_parser( - 'get-config', help='Read and print JSON config to stdout') - subparsers.add_parser( - 'merge-config', help='Merge JSON config from stdin with existing') + subparsers.add_parser('setup', help='Perform initial setup steps') + subparsers.add_parser('get-config', + help='Read and print JSON config to stdout') + subparsers.add_parser('merge-config', + help='Merge JSON config from stdin with existing') subparsers.required = True return parser.parse_args() diff --git a/actions/sharing b/actions/sharing index d40bd6319..2aa7390b4 100755 --- a/actions/sharing +++ b/actions/sharing @@ -58,8 +58,8 @@ def parse_arguments(): def load_augeas(): """Initialize augeas for this app's configuration file.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') aug.set('/augeas/load/Httpd/incl[last() + 1]', APACHE_CONFIGURATION) aug.load() @@ -191,8 +191,9 @@ def _list(aug=None): """Must contain the line 'Require all granted'.""" require = location + '//directive["Require"]' return bool(aug.match(require)) and aug.get( - require + '/arg[1]') == 'all' and aug.get( - require + '/arg[2]') == 'granted' + require + + '/arg[1]') == 'all' and aug.get(require + + '/arg[2]') == 'granted' for share in shares: if share['name'] == name: diff --git a/actions/ssh b/actions/ssh index 1c3035304..8c976364f 100755 --- a/actions/ssh +++ b/actions/ssh @@ -117,8 +117,8 @@ def subcommand_set_keys(arguments): def _load_augeas(): """Initialize augeas for this app's configuration file.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Sshd/lens', 'Sshd.lns') aug.set('/augeas/load/Sshd/incl[last() + 1]', '/etc/ssh/sshd_config') aug.load() diff --git a/actions/sshfs b/actions/sshfs index 5d5da431f..c348fc58d 100755 --- a/actions/sshfs +++ b/actions/sshfs @@ -96,11 +96,11 @@ def validate_mountpoint(mountpoint): """Check that the folder is empty, and create it if it doesn't exist""" if os.path.exists(mountpoint): if _is_mounted(mountpoint): - raise AlreadyMountedError( - 'Mountpoint %s already mounted' % mountpoint) + raise AlreadyMountedError('Mountpoint %s already mounted' % + mountpoint) if os.listdir(mountpoint) or not os.path.isdir(mountpoint): - raise ValueError( - 'Mountpoint %s is not an empty directory' % mountpoint) + raise ValueError('Mountpoint %s is not an empty directory' % + mountpoint) else: os.makedirs(mountpoint) diff --git a/actions/tahoe-lafs b/actions/tahoe-lafs index 5630d05a0..0036b030c 100755 --- a/actions/tahoe-lafs +++ b/actions/tahoe-lafs @@ -114,8 +114,8 @@ def subcommand_setup(arguments): def subcommand_autostart(_): """Automatically start all introducers and storage nodes on system startup. """ - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') aug.set('/augeas/load/Shellvars/incl[last() + 1]', DEFAULT_FILE) aug.load() @@ -157,8 +157,9 @@ def subcommand_create_storage_node(_): if not os.path.exists(os.path.join(tahoe_home, storage_node_name)): subprocess.check_call([ 'tahoe', 'create-node', '--nickname=\"storage_node\"', - '--webport=1234', '--hostname={}'.format( - get_configured_domain_name()), storage_node_name + '--webport=1234', + '--hostname={}'.format(get_configured_domain_name()), + storage_node_name ]) with open( os.path.join(tahoe_home, introducer_name, 'private', diff --git a/actions/timezone-change b/actions/timezone-change index cef4d764f..062299aa5 100755 --- a/actions/timezone-change +++ b/actions/timezone-change @@ -15,7 +15,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Set time zones with timedatectl (requires root permission). """ diff --git a/actions/tor b/actions/tor index 3690f3275..a66bba2ec 100755 --- a/actions/tor +++ b/actions/tor @@ -529,8 +529,8 @@ def _update_ports(): def augeas_load(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Tor/lens', 'Tor.lns') aug.set('/augeas/load/Tor/incl[last() + 1]', '/etc/tor/instances/plinth/torrc') diff --git a/actions/ttrss b/actions/ttrss index ec4bb7a05..362067abc 100755 --- a/actions/ttrss +++ b/actions/ttrss @@ -133,8 +133,8 @@ def _run_as_postgres(command, stdin=None, stdout=None): def load_augeas(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') aug.set('/augeas/load/Shellvars/incl[last() + 1]', DEFAULT_FILE) aug.set('/augeas/load/Phpvars/lens', 'Phpvars.lns') diff --git a/actions/users b/actions/users index e35ad320c..605b91156 100755 --- a/actions/users +++ b/actions/users @@ -210,8 +210,8 @@ def configure_ldapscripts(): # modify a copy of the config file shutil.copy('/etc/ldapscripts/ldapscripts.conf', LDAPSCRIPTS_CONF) - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') aug.set('/augeas/load/Shellvars/incl[last() + 1]', LDAPSCRIPTS_CONF) aug.load() diff --git a/functional_tests/step_definitions/application.py b/functional_tests/step_definitions/application.py index b5cbc1457..22db2c979 100644 --- a/functional_tests/step_definitions/application.py +++ b/functional_tests/step_definitions/application.py @@ -107,8 +107,7 @@ def select_domain_name(browser, app_name, domain_name): @given('the shadowsocks application is configured') def configure_shadowsocks(browser): - application.configure_shadowsocks(browser, 'example.com', - 'fakepassword') + application.configure_shadowsocks(browser, 'example.com', 'fakepassword') @when( @@ -128,8 +127,8 @@ def assert_shadowsocks_configuration(browser, server, password): password) == application.shadowsocks_get_configuration(browser) -@when( - parsers.parse('I modify the maximum file size of coquelicot to {size:d}')) +@when(parsers.parse('I modify the maximum file size of coquelicot to {size:d}') + ) def modify_max_file_size(browser, size): application.modify_max_file_size(browser, size) @@ -372,38 +371,55 @@ def tahoe_given_add_introducer(browser, domain): def tahoe_remove_introducer(browser, domain): application.tahoe_remove_introducer(browser, domain) -@given('the access rights are set to "only the owner can view or make changes"') + +@given('the access rights are set to "only the owner can view or make changes"' + ) def radicale_given_owner_only(browser): application.radicale_set_access_rights(browser, 'owner_only') -@given('the access rights are set to "any user can view, but only the owner can make changes"') + +@given( + 'the access rights are set to "any user can view, but only the owner can make changes"' +) def radicale_given_owner_write(browser): application.radicale_set_access_rights(browser, 'owner_write') + @given('the access rights are set to "any user can view or make changes"') def radicale_given_authenticated(browser): application.radicale_set_access_rights(browser, 'authenticated') -@when('I change the access rights to "only the owner can view or make changes"') + +@when('I change the access rights to "only the owner can view or make changes"' + ) def radicale_set_owner_only(browser): application.radicale_set_access_rights(browser, 'owner_only') -@when('I change the access rights to "any user can view, but only the owner can make changes"') + +@when( + 'I change the access rights to "any user can view, but only the owner can make changes"' +) def radicale_set_owner_write(browser): application.radicale_set_access_rights(browser, 'owner_write') + @when('I change the access rights to "any user can view or make changes"') def radicale_set_authenticated(browser): application.radicale_set_access_rights(browser, 'authenticated') + @then('the access rights should be "only the owner can view or make changes"') def radicale_check_owner_only(browser): assert application.radicale_get_access_rights(browser) == 'owner_only' -@then('the access rights should be "any user can view, but only the owner can make changes"') + +@then( + 'the access rights should be "any user can view, but only the owner can make changes"' +) def radicale_check_owner_write(browser): assert application.radicale_get_access_rights(browser) == 'owner_write' + @then('the access rights should be "any user can view or make changes"') def radicale_check_authenticated(browser): assert application.radicale_get_access_rights(browser) == 'authenticated' @@ -451,8 +467,8 @@ def app_visible_on_front_page(browser, app_name): assert len(shortcuts) == 1 -@then( - parsers.parse('{app_name:w} app should not be visible on the front page')) +@then(parsers.parse('{app_name:w} app should not be visible on the front page') + ) def app_not_visible_on_front_page(browser, app_name): shortcuts = application.find_on_front_page(browser, app_name) assert len(shortcuts) == 0 diff --git a/functional_tests/step_definitions/interface.py b/functional_tests/step_definitions/interface.py index 916e07532..257599cea 100644 --- a/functional_tests/step_definitions/interface.py +++ b/functional_tests/step_definitions/interface.py @@ -19,7 +19,6 @@ from pytest_bdd import given, parsers, then, when from support import config, interface - default_url = config['DEFAULT']['url'] @@ -52,8 +51,8 @@ def new_user_does_not_exist(browser, name): @given(parsers.parse('the user {name:w} exists')) def test_user_exists(browser, name): interface.nav_to_module(browser, 'users') - user_link = browser.find_link_by_href( - '/plinth/sys/users/' + name + '/edit/') + user_link = browser.find_link_by_href('/plinth/sys/users/' + name + + '/edit/') if not user_link: create_user(browser, name, 'secret123') diff --git a/functional_tests/step_definitions/site.py b/functional_tests/step_definitions/site.py index 100c0a269..5ede8366f 100644 --- a/functional_tests/step_definitions/site.py +++ b/functional_tests/step_definitions/site.py @@ -61,8 +61,9 @@ def verify_upload_password(browser, password): 'I upload the sample local file to coquelicot with password {password:w}' )) def coquelicot_upload_file(browser, sample_local_file, password): - url = site.upload_file_to_coquelicot( - browser, sample_local_file['file_path'], password) + url = site.upload_file_to_coquelicot(browser, + sample_local_file['file_path'], + password) sample_local_file['upload_url'] = url @@ -214,7 +215,8 @@ def syncthing_folder_not_present(browser, folder_name): @given( parsers.parse( - 'folder {folder_path:S} is present as syncthing folder {folder_name:w}')) + 'folder {folder_path:S} is present as syncthing folder {folder_name:w}' + )) def syncthing_folder_present(browser, folder_name, folder_path): if not site.syncthing_folder_is_present(browser, folder_name): site.syncthing_add_folder(browser, folder_name, folder_path) diff --git a/functional_tests/support/site.py b/functional_tests/support/site.py index 399853f9b..14632073e 100644 --- a/functional_tests/support/site.py +++ b/functional_tests/support/site.py @@ -294,8 +294,8 @@ def transmission_remove_all_torrents(browser): def transmission_upload_sample_torrent(browser): """Upload a sample torrent into transmission.""" browser.visit(config['DEFAULT']['url'] + '/transmission') - file_path = os.path.join( - os.path.dirname(__file__), '..', 'data', 'sample.torrent') + file_path = os.path.join(os.path.dirname(__file__), '..', 'data', + 'sample.torrent') browser.click_link_by_id('toolbar-open') eventually(browser.is_element_not_present_by_css, args=['#upload-container[style="display: none;"]']) @@ -396,9 +396,8 @@ def deluge_remove_all_torrents(browser): browser.find_by_id('remove').first.click() # Remove window shows up - assert eventually( - lambda: _deluge_get_active_window_title(browser) == 'Remove Torrent' - ) + assert eventually(lambda: _deluge_get_active_window_title(browser) == + 'Remove Torrent') _deluge_click_active_window_button(browser, 'Remove With Data') @@ -434,8 +433,8 @@ def deluge_upload_sample_torrent(browser): eventually( lambda: _deluge_get_active_window_title(browser) == 'Add Torrents') - file_path = os.path.join( - os.path.dirname(__file__), '..', 'data', 'sample.torrent') + file_path = os.path.join(os.path.dirname(__file__), '..', 'data', + 'sample.torrent') if browser.find_by_id('fileUploadForm'): # deluge-web 2.x browser.attach_file('file', file_path) @@ -443,9 +442,8 @@ def deluge_upload_sample_torrent(browser): browser.find_by_css('button.x-deluge-add-file').first.click() # Add from file window appears - eventually( - lambda: _deluge_get_active_window_title(browser) == 'Add from File' - ) + eventually(lambda: _deluge_get_active_window_title(browser) == + 'Add from File') # Attach file browser.attach_file('file', file_path) diff --git a/plinth/action_utils.py b/plinth/action_utils.py index c2f2e725d..aa5a2b7d8 100644 --- a/plinth/action_utils.py +++ b/plinth/action_utils.py @@ -211,7 +211,6 @@ def webserver_disable(name, kind='config', apply_changes=True): class WebserverChange(object): """Context to restart/reload Apache after configuration changes.""" - def __init__(self): """Initialize the context object state.""" self.actions_required = set() @@ -425,9 +424,10 @@ def diagnose_url_on_all(url, **kwargs): def diagnose_netcat(host, port, input='', negate=False): """Run a diagnostic using netcat.""" try: - process = subprocess.Popen( - ['nc', host, str(port)], stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + process = subprocess.Popen(['nc', host, str(port)], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) process.communicate(input=input.encode()) if process.returncode != 0: result = 'failed' diff --git a/plinth/app.py b/plinth/app.py index 085dc7dad..f23ed4f85 100644 --- a/plinth/app.py +++ b/plinth/app.py @@ -114,7 +114,6 @@ class Component: def enable(self): """Run operations to enable the component.""" - def disable(self): """Run operations to disable the component.""" diff --git a/plinth/context_processors.py b/plinth/context_processors.py index 39f82ed21..3af5d73a0 100644 --- a/plinth/context_processors.py +++ b/plinth/context_processors.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Django context processors to provide common data to templates. """ diff --git a/plinth/daemon.py b/plinth/daemon.py index 604502d64..6fc733461 100644 --- a/plinth/daemon.py +++ b/plinth/daemon.py @@ -23,7 +23,6 @@ from plinth import action_utils, actions, app class Daemon(app.LeaderComponent): """Component to manage a background daemon or any systemd unit.""" - def __init__(self, component_id, unit, strict_check=False): """Initialize a new daemon component. diff --git a/plinth/dbus.py b/plinth/dbus.py index ca4cad47e..3b3ec2efa 100755 --- a/plinth/dbus.py +++ b/plinth/dbus.py @@ -83,7 +83,6 @@ class PackageHandler(): class DBusServer(): """Abstraction over a connection to D-Bus.""" - def __init__(self): """Initialize the server object.""" self.package_handler = None diff --git a/plinth/forms.py b/plinth/forms.py index 1cacf78ef..7b0fa18df 100644 --- a/plinth/forms.py +++ b/plinth/forms.py @@ -43,7 +43,6 @@ class DomainSelectionForm(forms.Form): """Form for selecting a domain name to be used for distributed federated applications """ - def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -84,9 +83,9 @@ class LanguageSelectionFormMixin: plinth_dir = os.path.dirname(plinth.__file__) if language_code == 'en' or os.path.exists( os.path.join(plinth_dir, 'locale', locale_code)): - supported_languages.append((language_code, - _get_local_name( - language_code, language_name))) + supported_languages.append( + (language_code, + _get_local_name(language_code, language_name))) self.fields['language'].choices = supported_languages @@ -106,7 +105,6 @@ class CheckboxSelectMultipleWithReadOnly(forms.widgets.CheckboxSelectMultiple): Derived from https://djangosnippets.org/snippets/2786/ """ - def render(self, name, value, attrs=None, choices=(), renderer=None): if value is None: value = [] @@ -114,8 +112,8 @@ class CheckboxSelectMultipleWithReadOnly(forms.widgets.CheckboxSelectMultiple): output = [u'
    '] global_readonly = 'readonly' in final_attrs str_values = set([v for v in value]) - for i, (option_value, option_label) in enumerate( - chain(self.choices, choices)): + for i, (option_value, + option_label) in enumerate(chain(self.choices, choices)): if not global_readonly and 'readonly' in final_attrs: # If the entire group is readonly keep all options readonly del final_attrs['readonly'] diff --git a/plinth/kvstore.py b/plinth/kvstore.py index a9407b4ab..7d2d1408b 100644 --- a/plinth/kvstore.py +++ b/plinth/kvstore.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Simple key/value store using Django models """ diff --git a/plinth/middleware.py b/plinth/middleware.py index 827af8a48..83973303b 100644 --- a/plinth/middleware.py +++ b/plinth/middleware.py @@ -41,7 +41,6 @@ logger = logging.getLogger(__name__) class SetupMiddleware(MiddlewareMixin): """Django middleware to show pre-setup message and setup progress.""" - @staticmethod def process_view(request, view_func, view_args, view_kwargs): """Handle a request as Django middleware request handler.""" @@ -77,8 +76,8 @@ class SetupMiddleware(MiddlewareMixin): str(exception)) error_details = getattr(exception, 'error_details', '') message = _('Error installing application: {string} ' - '{details}').format( - string=error_string, details=error_details) + '{details}').format(string=error_string, + details=error_details) else: message = _('Error installing application: {error}') \ .format(error=exception) @@ -96,7 +95,6 @@ class SetupMiddleware(MiddlewareMixin): class AdminRequiredMiddleware(MiddlewareMixin): """Django middleware for authenticating requests for admin areas.""" - @staticmethod def process_view(request, view_func, view_args, view_kwargs): """Reject non-admin access to views that are private and not marked.""" @@ -110,7 +108,6 @@ class AdminRequiredMiddleware(MiddlewareMixin): class FirstSetupMiddleware(MiddlewareMixin): """Django middleware to block all interactions before first setup.""" - @staticmethod def process_view(request, view_func, view_args, view_kwargs): """Block all user interactions when first setup is pending.""" diff --git a/plinth/migrations/0001_initial.py b/plinth/migrations/0001_initial.py index c7c741922..3208d1a1c 100644 --- a/plinth/migrations/0001_initial.py +++ b/plinth/migrations/0001_initial.py @@ -18,7 +18,6 @@ # # Generated by Django 1.9 on 2015-12-04 07:27 # - """ Initial Django migration for FreedomBox to create database tables. """ @@ -33,8 +32,7 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( diff --git a/plinth/migrations/0003_merge_firstboot_completed_fields.py b/plinth/migrations/0003_merge_firstboot_completed_fields.py index 1e4c441a9..fd615d6d1 100644 --- a/plinth/migrations/0003_merge_firstboot_completed_fields.py +++ b/plinth/migrations/0003_merge_firstboot_completed_fields.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Remove the deprecated KVStore entries 'setup_state' and 'firstboot_state', and only use the new entry 'firstboot_completed' instead. @@ -63,8 +62,8 @@ def merge_firstboot_finished_fields(apps, schema_editor): firstboot_completed = _object.value # Set new 'firstboot_completed' if needed - new_firstboot_completed = bool(firstboot_completed or setup_state or - firstboot_state) + new_firstboot_completed = bool(firstboot_completed or setup_state + or firstboot_state) if new_firstboot_completed and not firstboot_completed: obj, created = KVStore.objects.get_or_create(key='firstboot_completed') obj.value = 1 diff --git a/plinth/migrations/0004_userprofile.py b/plinth/migrations/0004_userprofile.py index f193f2d0c..9dd6a868c 100644 --- a/plinth/migrations/0004_userprofile.py +++ b/plinth/migrations/0004_userprofile.py @@ -30,14 +30,17 @@ class Migration(migrations.Migration): migrations.CreateModel( name='UserProfile', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, - serialize=False, verbose_name='ID')), - ('language', models.CharField(default=None, max_length=32, - null=True)), - ('user', models.OneToOneField( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL)), - ], ), + ('id', + models.AutoField(auto_created=True, primary_key=True, + serialize=False, verbose_name='ID')), + ('language', + models.CharField(default=None, max_length=32, null=True)), + ('user', + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL)), + ], + ), migrations.RunPython(code=insert_users, reverse_code=truncate_user_profile), ] diff --git a/plinth/modules/apache/__init__.py b/plinth/modules/apache/__init__.py index 9d619c3f7..bb47a30d6 100644 --- a/plinth/modules/apache/__init__.py +++ b/plinth/modules/apache/__init__.py @@ -54,9 +54,9 @@ class ApacheApp(app_module.App): freedombox_ports = Firewall( 'firewall-plinth', - format_lazy( - _('{box_name} Web Interface (Plinth)'), box_name=_( - cfg.box_name)), ports=['http', 'https'], is_external=True) + format_lazy(_('{box_name} Web Interface (Plinth)'), + box_name=_(cfg.box_name)), ports=['http', 'https'], + is_external=True) self.add(freedombox_ports) letsencrypt = LetsEncrypt('letsencrypt-apache', domains='*', diff --git a/plinth/modules/apache/components.py b/plinth/modules/apache/components.py index 70fc64074..7fc22a753 100644 --- a/plinth/modules/apache/components.py +++ b/plinth/modules/apache/components.py @@ -23,7 +23,6 @@ from plinth import action_utils, actions, app class Webserver(app.LeaderComponent): """Component to enable/disable Apache configuration.""" - def __init__(self, component_id, web_name, kind='config'): """Initialize the web server component. @@ -62,7 +61,6 @@ class Webserver(app.LeaderComponent): class Uwsgi(app.LeaderComponent): """Component to enable/disable uWSGI configuration.""" - def __init__(self, component_id, uwsgi_name): """Initialize the uWSGI component. diff --git a/plinth/modules/apache/urls.py b/plinth/modules/apache/urls.py index 459a8096d..ecd727c94 100644 --- a/plinth/modules/apache/urls.py +++ b/plinth/modules/apache/urls.py @@ -14,10 +14,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the Apache module. """ -urlpatterns = [ -] +urlpatterns = [] diff --git a/plinth/modules/api/views.py b/plinth/modules/api/views.py index a1c5ebdc7..536f4056f 100644 --- a/plinth/modules/api/views.py +++ b/plinth/modules/api/views.py @@ -45,9 +45,8 @@ def shortcuts(request, **kwargs): # XXX: Get the module (or module name) from shortcut properly. username = str(request.user) if request.user.is_authenticated else None response = get_shortcuts_as_json(username) - return HttpResponse( - json.dumps(response, cls=DjangoJSONEncoder), - content_type='application/json') + return HttpResponse(json.dumps(response, cls=DjangoJSONEncoder), + content_type='application/json') def get_shortcuts_as_json(username=None): diff --git a/plinth/modules/avahi/__init__.py b/plinth/modules/avahi/__init__.py index 3cd585667..d58de5b9e 100644 --- a/plinth/modules/avahi/__init__.py +++ b/plinth/modules/avahi/__init__.py @@ -91,9 +91,10 @@ def init(): global app app = AvahiApp() if app.is_enabled(): - domain_added.send_robust( - sender='avahi', domain_type='domain-type-local', - name=get_hostname() + '.local', services='__all__') + domain_added.send_robust(sender='avahi', + domain_type='domain-type-local', + name=get_hostname() + '.local', + services='__all__') app.set_enabled(True) post_hostname_change.connect(on_post_hostname_change) diff --git a/plinth/modules/backups/__init__.py b/plinth/modules/backups/__init__.py index a4c7be23d..d355848b0 100644 --- a/plinth/modules/backups/__init__.py +++ b/plinth/modules/backups/__init__.py @@ -108,9 +108,8 @@ def _backup_handler(packet, encryption_passphrase=None): arguments = ['create-archive', '--path', packet.path, '--paths'] + paths input_data = '' if encryption_passphrase: - input_data = json.dumps({ - 'encryption_passphrase': encryption_passphrase - }) + input_data = json.dumps( + {'encryption_passphrase': encryption_passphrase}) actions.superuser_run('backups', arguments, input=input_data.encode()) diff --git a/plinth/modules/backups/api.py b/plinth/modules/backups/api.py index a6b0a9780..9e72ebc3b 100644 --- a/plinth/modules/backups/api.py +++ b/plinth/modules/backups/api.py @@ -82,7 +82,6 @@ def _validate_service(service): class BackupError: """Represent an backup/restore operation error.""" - def __init__(self, error_type, app, hook=None): """Initialize the error object.""" self.error_type = error_type @@ -98,7 +97,6 @@ class BackupError: class Packet: """Information passed to a handlers for backup/restore operations.""" - def __init__(self, operation, scope, root, apps=None, path=None): """Initialize the packet. @@ -240,7 +238,6 @@ def _install_apps_before_restore(apps): class BackupApp: """A application that can be backed up and its manifest.""" - def __init__(self, name, app): """Initialize object and load manfiest.""" self.name = name @@ -365,7 +362,6 @@ def _switch_to_subvolume(subvolume): class ServiceHandler: """Abstraction to help with service shutdown/restart.""" - @staticmethod def create(backup_app, service): service_type = 'system' @@ -400,7 +396,6 @@ class ServiceHandler: class SystemServiceHandler(ServiceHandler): """Handle starting and stopping of system services for backup.""" - def __init__(self, backup_app, service): """Initialize the object.""" super().__init__(backup_app, service) @@ -420,7 +415,6 @@ class SystemServiceHandler(ServiceHandler): class ApacheServiceHandler(ServiceHandler): """Handle starting and stopping of Apache services for backup.""" - def __init__(self, backup_app, service): """Initialize the object.""" super().__init__(backup_app, service) diff --git a/plinth/modules/backups/decorators.py b/plinth/modules/backups/decorators.py index ffa756f4d..03fae602f 100644 --- a/plinth/modules/backups/decorators.py +++ b/plinth/modules/backups/decorators.py @@ -30,7 +30,6 @@ def delete_tmp_backup_file(function): XXX: Implement a better way to delete uploaded files. """ - @functools.wraps(function) def wrapper(request, *args, **kwargs): path = request.session.get(SESSION_PATH_VARIABLE, None) diff --git a/plinth/modules/backups/repository.py b/plinth/modules/backups/repository.py index cb0fd8a31..7b57773b6 100644 --- a/plinth/modules/backups/repository.py +++ b/plinth/modules/backups/repository.py @@ -59,10 +59,8 @@ KNOWN_ERRORS = [ 'errors': [ 'not a valid repository', 'does not exist', 'FileNotFoundError' ], - 'message': - _('Repository not found'), - 'raise_as': - errors.BorgRepositoryDoesNotExistError, + 'message': _('Repository not found'), + 'raise_as': errors.BorgRepositoryDoesNotExistError, }, { 'errors': ['passphrase supplied in .* is incorrect'], @@ -176,7 +174,6 @@ class BaseBorgRepository(abc.ABC): def remove(self): """Remove a borg repository""" - def list_archives(self): """Return list of archives in this repository.""" output = self.run(['list-repo', '--path', self.borg_path]) @@ -241,7 +238,6 @@ class BaseBorgRepository(abc.ABC): def get_download_stream(self, archive_name): """Return an stream of .tar.gz binary data for a backup archive.""" - class BufferedReader(io.BufferedReader): """Improve performance of buffered binary streaming. @@ -255,7 +251,6 @@ class BaseBorgRepository(abc.ABC): binary data. """ - def __next__(self): """Override to call read() instead of readline().""" chunk = self.read(io.DEFAULT_BUFFER_SIZE) diff --git a/plinth/modules/backups/tests/test_api.py b/plinth/modules/backups/tests/test_api.py index 5b4bba46a..c8436a7b3 100644 --- a/plinth/modules/backups/tests/test_api.py +++ b/plinth/modules/backups/tests/test_api.py @@ -57,7 +57,6 @@ def _get_backup_app(name): class TestBackupApp: """Test the BackupApp class.""" - @staticmethod def test_run_hook(): """Test running a hook on an application.""" @@ -82,7 +81,6 @@ class TestBackupApp: @pytest.mark.usefixtures('load_cfg') class TestBackupProcesses: """Test cases for backup processes""" - @staticmethod def test_packet_process_manifests(): """Test that directories/files are collected from manifests.""" @@ -239,7 +237,6 @@ class TestBackupProcesses: class TestBackupModule: """Tests of the backups django module, like views or forms.""" - @staticmethod def test_file_upload(): # posting a video should fail diff --git a/plinth/modules/cockpit/utils.py b/plinth/modules/cockpit/utils.py index 6965621ad..b54a9a7c7 100644 --- a/plinth/modules/cockpit/utils.py +++ b/plinth/modules/cockpit/utils.py @@ -27,8 +27,8 @@ CONFIG_FILE = '/etc/cockpit/cockpit.conf' def load_augeas(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/inifile/lens', 'Puppet.lns') aug.set('/augeas/load/inifile/incl[last() + 1]', CONFIG_FILE) aug.load() diff --git a/plinth/modules/config/__init__.py b/plinth/modules/config/__init__.py index e732f1f81..6db06b41f 100644 --- a/plinth/modules/config/__init__.py +++ b/plinth/modules/config/__init__.py @@ -81,8 +81,8 @@ def get_hostname(): def _get_home_page_url(): """Get the default application for the domain.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') conf_file = APACHE_HOMEPAGE_CONFIG if os.path.exists( APACHE_HOMEPAGE_CONFIG) else FREEDOMBOX_APACHE_CONFIG diff --git a/plinth/modules/config/forms.py b/plinth/modules/config/forms.py index ea11ddb94..cd01e6c1e 100644 --- a/plinth/modules/config/forms.py +++ b/plinth/modules/config/forms.py @@ -67,11 +67,10 @@ class ConfigurationForm(forms.Form): 'end with an alphabet or a digit and have as interior ' 'characters only alphabets, digits and hyphens. Total ' 'length must be 63 characters or less.'), - box_name=ugettext_lazy(cfg.box_name)), - validators=[ - validators.RegexValidator(HOSTNAME_REGEX, - ugettext_lazy('Invalid hostname')) - ], strip=True) + box_name=ugettext_lazy(cfg.box_name)), validators=[ + validators.RegexValidator(HOSTNAME_REGEX, + ugettext_lazy('Invalid hostname')) + ], strip=True) domainname = forms.CharField( label=ugettext_lazy('Domain Name'), help_text=format_lazy( @@ -83,12 +82,12 @@ class ConfigurationForm(forms.Form): 'only alphabets, digits and hyphens. Length of each label ' 'must be 63 characters or less. Total length of domain name ' 'must be 253 characters or less.'), - box_name=ugettext_lazy(cfg.box_name)), - required=False, validators=[ - validators.RegexValidator( - r'^[a-zA-Z0-9]([-a-zA-Z0-9.]{,251}[a-zA-Z0-9])?$', - ugettext_lazy('Invalid domain name')), domain_label_validator - ], strip=True) + box_name=ugettext_lazy(cfg.box_name)), required=False, validators=[ + validators.RegexValidator( + r'^[a-zA-Z0-9]([-a-zA-Z0-9.]{,251}[a-zA-Z0-9])?$', + ugettext_lazy('Invalid domain name')), + domain_label_validator + ], strip=True) homepage = forms.ChoiceField( label=ugettext_lazy('Webserver Home Page'), help_text=format_lazy( diff --git a/plinth/modules/diagnostics/urls.py b/plinth/modules/diagnostics/urls.py index 56ff7ef0b..ace9382e3 100644 --- a/plinth/modules/diagnostics/urls.py +++ b/plinth/modules/diagnostics/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the Diagnostics module """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import diagnostics as views - urlpatterns = [ url(r'^sys/diagnostics/$', views.index, name='index'), url(r'^sys/diagnostics/(?P[1-9a-z\-]+)/$', views.module, diff --git a/plinth/modules/diaspora/__init__.py b/plinth/modules/diaspora/__init__.py index 0575154c6..4452a8627 100644 --- a/plinth/modules/diaspora/__init__.py +++ b/plinth/modules/diaspora/__init__.py @@ -89,9 +89,10 @@ class DiasporaApp(app_module.App): parent_url_name='apps') self.add(menu_item) - shortcut = Shortcut( - 'shortcut-diaspora', name, short_description=short_description, - icon='diaspora', url=None, clients=clients, login_required=True) + shortcut = Shortcut('shortcut-diaspora', name, + short_description=short_description, + icon='diaspora', url=None, clients=clients, + login_required=True) self.add(shortcut) firewall = Firewall('firewall-diaspora', name, ports=['http', 'https'], @@ -107,7 +108,6 @@ class DiasporaApp(app_module.App): class Shortcut(frontpage.Shortcut): """Frontpage shortcut to use configured domain name for URL.""" - def enable(self): """Set the proper shortcut URL when enabled.""" super().enable() @@ -179,8 +179,8 @@ def generate_apache_configuration(conf_file, domain_name): diaspora_domain_name = ".".join(["diaspora", domain_name]) - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') aug.set('/augeas/load/Httpd/incl[last() + 1]', conf_file) diff --git a/plinth/modules/diaspora/manifest.py b/plinth/modules/diaspora/manifest.py index e0c968602..d98cda5d9 100644 --- a/plinth/modules/diaspora/manifest.py +++ b/plinth/modules/diaspora/manifest.py @@ -40,8 +40,9 @@ clients = validate([{ 'type': 'web', 'url': - format_lazy('https://diaspora.{host}', - host=diaspora.get_configured_domain_name() if - diaspora.is_setup() else "") + format_lazy( + 'https://diaspora.{host}', + host=diaspora.get_configured_domain_name() + if diaspora.is_setup() else "") }] }]) diff --git a/plinth/modules/dynamicdns/__init__.py b/plinth/modules/dynamicdns/__init__.py index a06b343fc..c96a7dc52 100644 --- a/plinth/modules/dynamicdns/__init__.py +++ b/plinth/modules/dynamicdns/__init__.py @@ -86,9 +86,10 @@ def init(): app = DynamicDNSApp() current_status = get_status() if current_status['enabled']: - domain_added.send_robust( - sender='dynamicdns', domain_type='domain-type-dynamic', - name=current_status['dynamicdns_domain'], services='__all__') + domain_added.send_robust(sender='dynamicdns', + domain_type='domain-type-dynamic', + name=current_status['dynamicdns_domain'], + services='__all__') app.set_enabled(True) diff --git a/plinth/modules/dynamicdns/forms.py b/plinth/modules/dynamicdns/forms.py index d22197d7b..397fc6c06 100644 --- a/plinth/modules/dynamicdns/forms.py +++ b/plinth/modules/dynamicdns/forms.py @@ -28,7 +28,6 @@ from plinth.utils import format_lazy class TrimmedCharField(forms.CharField): """Trim the contents of a CharField.""" - def clean(self, value): """Clean and validate the field value""" if value: @@ -81,12 +80,12 @@ class ConfigureForm(forms.Form): 'freedns.afraid.org'), ('other', 'other update URL')) - enabled = forms.BooleanField( - label=ugettext_lazy('Enable Dynamic DNS'), required=False) + enabled = forms.BooleanField(label=ugettext_lazy('Enable Dynamic DNS'), + required=False) - service_type = forms.ChoiceField( - label=ugettext_lazy('Service Type'), help_text=help_services, - choices=provider_choices) + service_type = forms.ChoiceField(label=ugettext_lazy('Service Type'), + help_text=help_services, + choices=provider_choices) dynamicdns_server = TrimmedCharField( label=ugettext_lazy('GnuDIP Server Address'), required=False, @@ -95,9 +94,9 @@ class ConfigureForm(forms.Form): ugettext_lazy('Invalid server name')) ]) - dynamicdns_update_url = TrimmedCharField( - label=ugettext_lazy('Update URL'), required=False, - help_text=help_update_url) + dynamicdns_update_url = TrimmedCharField(label=ugettext_lazy('Update URL'), + required=False, + help_text=help_update_url) disable_SSL_cert_check = forms.BooleanField( label=ugettext_lazy('Accept all SSL certificates'), @@ -114,15 +113,15 @@ class ConfigureForm(forms.Form): ugettext_lazy('Invalid domain name')) ]) - dynamicdns_user = TrimmedCharField( - label=ugettext_lazy('Username'), required=False, help_text=help_user) + dynamicdns_user = TrimmedCharField(label=ugettext_lazy('Username'), + required=False, help_text=help_user) - dynamicdns_secret = TrimmedCharField( - label=ugettext_lazy('Password'), widget=forms.PasswordInput(), - required=False, help_text=help_secret) + dynamicdns_secret = TrimmedCharField(label=ugettext_lazy('Password'), + widget=forms.PasswordInput(), + required=False, help_text=help_secret) - showpw = forms.BooleanField( - label=ugettext_lazy('Show password'), required=False) + showpw = forms.BooleanField(label=ugettext_lazy('Show password'), + required=False) dynamicdns_ipurl = TrimmedCharField( label=ugettext_lazy('URL to look up public IP'), required=False, diff --git a/plinth/modules/dynamicdns/views.py b/plinth/modules/dynamicdns/views.py index 5827f500a..b00df9b18 100644 --- a/plinth/modules/dynamicdns/views.py +++ b/plinth/modules/dynamicdns/views.py @@ -39,15 +39,13 @@ EMPTYSTRING = 'none' subsubmenu = [{ 'url': reverse_lazy('dynamicdns:index'), 'text': ugettext_lazy('About') -}, - { - 'url': reverse_lazy('dynamicdns:configure'), - 'text': ugettext_lazy('Configure') - }, - { - 'url': reverse_lazy('dynamicdns:statuspage'), - 'text': ugettext_lazy('Status') - }] +}, { + 'url': reverse_lazy('dynamicdns:configure'), + 'text': ugettext_lazy('Configure') +}, { + 'url': reverse_lazy('dynamicdns:statuspage'), + 'text': ugettext_lazy('Status') +}] def index(request): @@ -164,9 +162,10 @@ def _apply_changes(request, old_status, new_status): _run(['stop']) if new_status['enabled']: - domain_added.send_robust( - sender='dynamicdns', domain_type='domain-type-dynamic', - name=new_status['dynamicdns_domain'], services='__all__') + domain_added.send_robust(sender='dynamicdns', + domain_type='domain-type-dynamic', + name=new_status['dynamicdns_domain'], + services='__all__') _run(['start']) messages.success(request, _('Configuration updated')) diff --git a/plinth/modules/firewall/tests/test_components.py b/plinth/modules/firewall/tests/test_components.py index 88f571b37..cf5bac265 100644 --- a/plinth/modules/firewall/tests/test_components.py +++ b/plinth/modules/firewall/tests/test_components.py @@ -77,7 +77,6 @@ def test_port_details(get_port_details): @patch('plinth.modules.firewall.get_enabled_services') def test_enable(get_enabled_services, add_service): """Test enabling a firewall component.""" - def get_enabled_services_side_effect(zone): return {'internal': ['test-port1'], 'external': ['test-port2']}[zone] diff --git a/plinth/modules/firewall/urls.py b/plinth/modules/firewall/urls.py index ae949c8d1..d6e2ddc4f 100644 --- a/plinth/modules/firewall/urls.py +++ b/plinth/modules/firewall/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the Firewall module """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^sys/firewall/$', views.index, name='index'), ] diff --git a/plinth/modules/first_boot/middleware.py b/plinth/modules/first_boot/middleware.py index 914079afb..075285e2c 100644 --- a/plinth/modules/first_boot/middleware.py +++ b/plinth/modules/first_boot/middleware.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Django middleware to redirect to firstboot wizard if it has not be run yet. @@ -34,7 +33,6 @@ LOGGER = logging.getLogger(__name__) class FirstBootMiddleware(MiddlewareMixin): """Forward to firstboot page if firstboot isn't finished yet.""" - @staticmethod def process_request(request): """Handle a request as Django middleware request handler.""" diff --git a/plinth/modules/gitweb/__init__.py b/plinth/modules/gitweb/__init__.py index 2970349eb..57730a903 100644 --- a/plinth/modules/gitweb/__init__.py +++ b/plinth/modules/gitweb/__init__.py @@ -78,10 +78,11 @@ class GitwebApp(app_module.App): 'gitweb:index', parent_url_name='apps') self.add(menu_item) - shortcut = frontpage.Shortcut( - 'shortcut-gitweb', name, short_description=short_description, - icon=icon_filename, url='/gitweb/', clients=clients, - login_required=True, allowed_groups=[group[0]]) + shortcut = frontpage.Shortcut('shortcut-gitweb', name, + short_description=short_description, + icon=icon_filename, url='/gitweb/', + clients=clients, login_required=True, + allowed_groups=[group[0]]) self.add(shortcut) firewall = Firewall('firewall-gitweb', name, ports=['http', 'https'], @@ -154,7 +155,6 @@ class GitwebApp(app_module.App): class GitwebWebserverAuth(Webserver): """Component to handle Gitweb authentication webserver configuration.""" - def is_conf_enabled(self): """Check whether Gitweb authentication configuration is enabled.""" return super().is_enabled() diff --git a/plinth/modules/gitweb/forms.py b/plinth/modules/gitweb/forms.py index a4b0181e8..0722ae1f1 100644 --- a/plinth/modules/gitweb/forms.py +++ b/plinth/modules/gitweb/forms.py @@ -83,9 +83,9 @@ class CreateRepoForm(forms.Form): label=_('Description of the repository'), strip=True, required=False, help_text=_('Optional, for displaying on Gitweb.')) - owner = forms.CharField( - label=_('Repository\'s owner name'), strip=True, required=False, - help_text=_('Optional, for displaying on Gitweb.')) + owner = forms.CharField(label=_('Repository\'s owner name'), strip=True, + required=False, + help_text=_('Optional, for displaying on Gitweb.')) is_private = forms.BooleanField( label=_('Private repository'), required=False, diff --git a/plinth/modules/gitweb/tests/test_gitweb.py b/plinth/modules/gitweb/tests/test_gitweb.py index 52b646c2b..254e0c613 100644 --- a/plinth/modules/gitweb/tests/test_gitweb.py +++ b/plinth/modules/gitweb/tests/test_gitweb.py @@ -30,8 +30,8 @@ from django.forms import ValidationError def _action_file(): """Return the path to the 'gitweb' actions file.""" current_directory = pathlib.Path(__file__).parent - return str( - current_directory / '..' / '..' / '..' / '..' / 'actions' / 'gitweb') + return str(current_directory / '..' / '..' / '..' / '..' / 'actions' / + 'gitweb') gitweb_actions = imp.load_source('gitweb', _action_file()) @@ -40,7 +40,6 @@ gitweb_actions = imp.load_source('gitweb', _action_file()) @pytest.fixture(name='call_action') def fixture_call_action(tmpdir, capsys): """Run actions with custom repo root path.""" - def _call_action(args, **kwargs): gitweb_actions.GIT_REPO_PATH = str(tmpdir) with patch('argparse._sys.argv', ['gitweb'] + args): diff --git a/plinth/modules/i2p/__init__.py b/plinth/modules/i2p/__init__.py index a38ee2336..0ab5d430b 100644 --- a/plinth/modules/i2p/__init__.py +++ b/plinth/modules/i2p/__init__.py @@ -89,10 +89,11 @@ class I2PApp(app_module.App): 'i2p:index', parent_url_name='apps') self.add(menu_item) - shortcut = frontpage.Shortcut( - 'shortcut-i2p', name, short_description=short_description, - icon=icon_filename, url='/i2p/', clients=clients, login_required=True, - allowed_groups=[group[0]]) + shortcut = frontpage.Shortcut('shortcut-i2p', name, + short_description=short_description, + icon=icon_filename, url='/i2p/', + clients=clients, login_required=True, + allowed_groups=[group[0]]) self.add(shortcut) firewall = Firewall('firewall-i2p-web', name, ports=['http', 'https'], diff --git a/plinth/modules/i2p/helpers.py b/plinth/modules/i2p/helpers.py index c74138c2d..0e610792a 100644 --- a/plinth/modules/i2p/helpers.py +++ b/plinth/modules/i2p/helpers.py @@ -35,7 +35,6 @@ class TunnelEditor(): :type aug: augeas.Augeas """ - def __init__(self, conf_filename=None, idx=None): self.conf_filename = conf_filename or FILE_TUNNEL_CONF self.idx = idx @@ -55,8 +54,8 @@ class TunnelEditor(): Chainable method. """ - self.aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + self.aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) self.aug.set('/augeas/load/Properties/lens', 'Properties.lns') self.aug.set('/augeas/load/Properties/incl[last() + 1]', self.conf_filename) @@ -160,8 +159,8 @@ class RouterEditor(): Chainable method. """ - self.aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + self.aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) self.aug.set('/augeas/load/Properties/lens', 'Properties.lns') self.aug.set('/augeas/load/Properties/incl[last() + 1]', self.conf_filename) diff --git a/plinth/modules/i2p/resources.py b/plinth/modules/i2p/resources.py index b6b9df7fd..2a7c34dbe 100644 --- a/plinth/modules/i2p/resources.py +++ b/plinth/modules/i2p/resources.py @@ -18,110 +18,92 @@ Pre-defined list of favorites for I2P and some additional favorites. """ -DEFAULT_FAVORITES = [ - { - 'name': 'anoncoin.i2p', - 'description': 'The Anoncoin project', - 'icon': '/themes/console/images/anoncoin_32.png', - 'url': 'http://anoncoin.i2p/' - }, - { - 'name': 'Dev Builds', - 'description': 'Development builds of I2P', - 'icon': '/themes/console/images/script_gear.png', - 'url': 'http://bobthebuilder.i2p/' - }, - { - 'name': 'Dev Forum', - 'description': 'Development forum', - 'icon': '/themes/console/images/group_gear.png', - 'url': 'http://zzz.i2p/' - }, - { - 'name': 'echelon.i2p', - 'description': 'I2P Applications', - 'icon': '/themes/console/images/box_open.png', - 'url': 'http://echelon.i2p/' - }, - { - 'name': 'exchanged.i2p', - 'description': 'Anonymous cryptocurrency exchange', - 'icon': '/themes/console/images/exchanged.png', - 'url': 'http://exchanged.i2p/' - }, - { - 'name': 'I2P Bug Reports', - 'description': 'Bug tracker', - 'icon': '/themes/console/images/bug.png', - 'url': 'http://trac.i2p2.i2p/report/1' - }, - { - 'name': 'I2P FAQ', - 'description': 'Frequently Asked Questions', - 'icon': '/themes/console/images/question.png', - 'url': 'http://i2p-projekt.i2p/faq' - }, - { - 'name': 'I2P Forum', - 'description': 'Community forum', - 'icon': '/themes/console/images/group.png', - 'url': 'http://i2pforum.i2p/' - }, - { - 'name': 'I2P Plugins', - 'description': 'Add-on directory', - 'icon': '/themes/console/images/info/plugin_link.png', - 'url': 'http://i2pwiki.i2p/index.php?title=Plugins' - }, - { - 'name': 'I2P Technical Docs', - 'description': 'Technical documentation', - 'icon': '/themes/console/images/education.png', - 'url': 'http://i2p-projekt.i2p/how' - }, - { - 'name': 'I2P Wiki', - 'description': 'Anonymous wiki - share the knowledge', - 'icon': '/themes/console/images/i2pwiki_logo.png', - 'url': 'http://i2pwiki.i2p/' - }, - { - 'name': 'Planet I2P', - 'description': 'I2P News', - 'icon': '/themes/console/images/world.png', - 'url': 'http://planet.i2p/' - }, - { - 'name': 'PrivateBin', - 'description': 'Encrypted I2P Pastebin', - 'icon': '/themes/console/images/paste_plain.png', - 'url': 'http://paste.crypthost.i2p/' - }, - { - 'name': 'Project Website', - 'description': 'I2P home page', - 'icon': '/themes/console/images/info_rhombus.png', - 'url': 'http://i2p-projekt.i2p/' - }, - { - 'name': 'stats.i2p', - 'description': 'I2P Network Statistics', - 'icon': '/themes/console/images/chart_line.png', - 'url': 'http://stats.i2p/cgi-bin/dashboard.cgi' - }, - { - 'name': 'The Tin Hat', - 'description': 'Privacy guides and tutorials', - 'icon': '/themes/console/images/thetinhat.png', - 'url': 'http://secure.thetinhat.i2p/' - }, - { - 'name': 'Trac Wiki', - 'description': '', - 'icon': '/themes/console/images/billiard_marker.png', - 'url': 'http://trac.i2p2.i2p/' - } -] +DEFAULT_FAVORITES = [{ + 'name': 'anoncoin.i2p', + 'description': 'The Anoncoin project', + 'icon': '/themes/console/images/anoncoin_32.png', + 'url': 'http://anoncoin.i2p/' +}, { + 'name': 'Dev Builds', + 'description': 'Development builds of I2P', + 'icon': '/themes/console/images/script_gear.png', + 'url': 'http://bobthebuilder.i2p/' +}, { + 'name': 'Dev Forum', + 'description': 'Development forum', + 'icon': '/themes/console/images/group_gear.png', + 'url': 'http://zzz.i2p/' +}, { + 'name': 'echelon.i2p', + 'description': 'I2P Applications', + 'icon': '/themes/console/images/box_open.png', + 'url': 'http://echelon.i2p/' +}, { + 'name': 'exchanged.i2p', + 'description': 'Anonymous cryptocurrency exchange', + 'icon': '/themes/console/images/exchanged.png', + 'url': 'http://exchanged.i2p/' +}, { + 'name': 'I2P Bug Reports', + 'description': 'Bug tracker', + 'icon': '/themes/console/images/bug.png', + 'url': 'http://trac.i2p2.i2p/report/1' +}, { + 'name': 'I2P FAQ', + 'description': 'Frequently Asked Questions', + 'icon': '/themes/console/images/question.png', + 'url': 'http://i2p-projekt.i2p/faq' +}, { + 'name': 'I2P Forum', + 'description': 'Community forum', + 'icon': '/themes/console/images/group.png', + 'url': 'http://i2pforum.i2p/' +}, { + 'name': 'I2P Plugins', + 'description': 'Add-on directory', + 'icon': '/themes/console/images/info/plugin_link.png', + 'url': 'http://i2pwiki.i2p/index.php?title=Plugins' +}, { + 'name': 'I2P Technical Docs', + 'description': 'Technical documentation', + 'icon': '/themes/console/images/education.png', + 'url': 'http://i2p-projekt.i2p/how' +}, { + 'name': 'I2P Wiki', + 'description': 'Anonymous wiki - share the knowledge', + 'icon': '/themes/console/images/i2pwiki_logo.png', + 'url': 'http://i2pwiki.i2p/' +}, { + 'name': 'Planet I2P', + 'description': 'I2P News', + 'icon': '/themes/console/images/world.png', + 'url': 'http://planet.i2p/' +}, { + 'name': 'PrivateBin', + 'description': 'Encrypted I2P Pastebin', + 'icon': '/themes/console/images/paste_plain.png', + 'url': 'http://paste.crypthost.i2p/' +}, { + 'name': 'Project Website', + 'description': 'I2P home page', + 'icon': '/themes/console/images/info_rhombus.png', + 'url': 'http://i2p-projekt.i2p/' +}, { + 'name': 'stats.i2p', + 'description': 'I2P Network Statistics', + 'icon': '/themes/console/images/chart_line.png', + 'url': 'http://stats.i2p/cgi-bin/dashboard.cgi' +}, { + 'name': 'The Tin Hat', + 'description': 'Privacy guides and tutorials', + 'icon': '/themes/console/images/thetinhat.png', + 'url': 'http://secure.thetinhat.i2p/' +}, { + 'name': 'Trac Wiki', + 'description': '', + 'icon': '/themes/console/images/billiard_marker.png', + 'url': 'http://trac.i2p2.i2p/' +}] ADDITIONAL_FAVORITES = [ { 'name': 'Searx instance', diff --git a/plinth/modules/i2p/views.py b/plinth/modules/i2p/views.py index 62892ed93..74dec44d8 100644 --- a/plinth/modules/i2p/views.py +++ b/plinth/modules/i2p/views.py @@ -32,11 +32,10 @@ subsubmenu = [{ }, { 'url': reverse_lazy('i2p:tunnels'), 'text': ugettext_lazy('Proxies') -}, - { - 'url': reverse_lazy('i2p:torrents'), - 'text': ugettext_lazy('Anonymous torrents') - }] +}, { + 'url': reverse_lazy('i2p:torrents'), + 'text': ugettext_lazy('Anonymous torrents') +}] class I2PAppView(AppView): diff --git a/plinth/modules/ikiwiki/__init__.py b/plinth/modules/ikiwiki/__init__.py index 558dbeb44..e4eaf2033 100644 --- a/plinth/modules/ikiwiki/__init__.py +++ b/plinth/modules/ikiwiki/__init__.py @@ -92,8 +92,7 @@ class IkiwikiApp(app_module.App): """Add an ikiwiki shortcut to frontpage.""" shortcut = frontpage.Shortcut('shortcut-ikiwiki-' + site, title, icon=icon_filename, - url='/ikiwiki/' + site, - clients=clients) + url='/ikiwiki/' + site, clients=clients) self.add(shortcut) return shortcut diff --git a/plinth/modules/ikiwiki/forms.py b/plinth/modules/ikiwiki/forms.py index 433d9f0b7..812b3bee6 100644 --- a/plinth/modules/ikiwiki/forms.py +++ b/plinth/modules/ikiwiki/forms.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Forms for configuring ikiwiki """ @@ -25,14 +24,12 @@ from django.utils.translation import ugettext_lazy as _ class IkiwikiCreateForm(forms.Form): """Form to create a wiki or blog.""" - site_type = forms.ChoiceField( - label=_('Type'), - choices=[('wiki', 'Wiki'), ('blog', 'Blog')]) + site_type = forms.ChoiceField(label=_('Type'), choices=[('wiki', 'Wiki'), + ('blog', 'Blog')]) name = forms.CharField(label=_('Name')) admin_name = forms.CharField(label=_('Admin Account Name')) - admin_password = forms.CharField( - label=_('Admin Account Password'), - widget=forms.PasswordInput()) + admin_password = forms.CharField(label=_('Admin Account Password'), + widget=forms.PasswordInput()) diff --git a/plinth/modules/ikiwiki/manifest.py b/plinth/modules/ikiwiki/manifest.py index b5fcda0e7..50dc252ea 100644 --- a/plinth/modules/ikiwiki/manifest.py +++ b/plinth/modules/ikiwiki/manifest.py @@ -28,8 +28,7 @@ clients = validate([{ }] }]) -backup = validate_backup({ - 'data': { +backup = validate_backup( + {'data': { 'directories': ['/var/lib/ikiwiki/', '/var/www/ikiwiki/'] - } -}) + }}) diff --git a/plinth/modules/jsxc/__init__.py b/plinth/modules/jsxc/__init__.py index 4fb4475f4..3ec4756ca 100644 --- a/plinth/modules/jsxc/__init__.py +++ b/plinth/modules/jsxc/__init__.py @@ -63,10 +63,11 @@ class JSXCApp(app_module.App): 'jsxc:index', parent_url_name='apps') self.add(menu_item) - shortcut = frontpage.Shortcut( - 'shortcut-jsxc', name=name, short_description=short_description, - icon=icon_filename, - url=reverse_lazy('jsxc:jsxc'), clients=clients) + shortcut = frontpage.Shortcut('shortcut-jsxc', name=name, + short_description=short_description, + icon=icon_filename, + url=reverse_lazy('jsxc:jsxc'), + clients=clients) self.add(shortcut) firewall = Firewall('firewall-jsxc', name, ports=['http', 'https'], diff --git a/plinth/modules/letsencrypt/components.py b/plinth/modules/letsencrypt/components.py index f7a69cab0..aaa352288 100644 --- a/plinth/modules/letsencrypt/components.py +++ b/plinth/modules/letsencrypt/components.py @@ -326,9 +326,10 @@ class LetsEncrypt(app.FollowerComponent): source_certificate_path, private_key_path, certificate_path) else: - self._copy_certificate( - source_private_key_path, source_certificate_path, - self.private_key_path, self.certificate_path) + self._copy_certificate(source_private_key_path, + source_certificate_path, + self.private_key_path, + self.certificate_path) def _copy_certificate(self, source_private_key_path, source_certificate_path, private_key_path, @@ -374,8 +375,8 @@ def on_certificate_event(event, domains, lineage): certificate changes. """ - threading.Thread(target=on_certificate_event_sync, args=(event, domains, - lineage)).start() + threading.Thread(target=on_certificate_event_sync, + args=(event, domains, lineage)).start() def on_certificate_event_sync(event, domains, lineage): diff --git a/plinth/modules/matrixsynapse/__init__.py b/plinth/modules/matrixsynapse/__init__.py index a35926aa3..08ea2ebaa 100644 --- a/plinth/modules/matrixsynapse/__init__.py +++ b/plinth/modules/matrixsynapse/__init__.py @@ -108,9 +108,8 @@ class MatrixSynapseApp(app_module.App): self.add(webserver) letsencrypt = LetsEncrypt( - 'letsencrypt-matrixsynapse', domains=get_domains, daemons=[ - managed_services[0] - ], should_copy_certificates=True, + 'letsencrypt-matrixsynapse', domains=get_domains, + daemons=[managed_services[0]], should_copy_certificates=True, private_key_path='/etc/matrix-synapse/homeserver.tls.key', certificate_path='/etc/matrix-synapse/homeserver.tls.crt', user_owner='matrix-synapse', group_owner='nogroup', diff --git a/plinth/modules/mediawiki/__init__.py b/plinth/modules/mediawiki/__init__.py index 4bd4aeba0..e945cba0a 100644 --- a/plinth/modules/mediawiki/__init__.py +++ b/plinth/modules/mediawiki/__init__.py @@ -101,7 +101,6 @@ class MediaWikiApp(app_module.App): class Shortcut(frontpage.Shortcut): """Frontpage shortcut for only logged users when in private mode.""" - def enable(self): """When enabled, check if MediaWiki is in private mode.""" super().enable() diff --git a/plinth/modules/minetest/__init__.py b/plinth/modules/minetest/__init__.py index d5a651247..ffa928ea4 100644 --- a/plinth/modules/minetest/__init__.py +++ b/plinth/modules/minetest/__init__.py @@ -132,8 +132,8 @@ def diagnose(): def load_augeas(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Php/lens', 'Php.lns') aug.set('/augeas/load/Php/incl[last() + 1]', CONFIG_FILE) aug.load() diff --git a/plinth/modules/minetest/forms.py b/plinth/modules/minetest/forms.py index 31afa21a7..0af0e0f18 100644 --- a/plinth/modules/minetest/forms.py +++ b/plinth/modules/minetest/forms.py @@ -28,9 +28,9 @@ class MinetestForm(AppForm): """Minetest configuration form""" max_players = forms.IntegerField( label=_('Maximum number of players'), required=True, min_value=1, - max_value=100, help_text=_( - 'You can change the maximum number of players playing ' - 'minetest at a single instance of time.')) + max_value=100, + help_text=_('You can change the maximum number of players playing ' + 'minetest at a single instance of time.')) creative_mode = forms.BooleanField( label=_('Enable creative mode'), required=False, diff --git a/plinth/modules/mldonkey/__init__.py b/plinth/modules/mldonkey/__init__.py index 3c73ad8b3..6c204756b 100644 --- a/plinth/modules/mldonkey/__init__.py +++ b/plinth/modules/mldonkey/__init__.py @@ -80,10 +80,11 @@ class MLDonkeyApp(app_module.App): parent_url_name='apps') self.add(menu_item) - shortcuts = frontpage.Shortcut( - 'shortcut-mldonkey', name, short_description=short_description, - icon=icon_filename, url='/mldonkey/', login_required=True, - clients=clients, allowed_groups=[group[0]]) + shortcuts = frontpage.Shortcut('shortcut-mldonkey', name, + short_description=short_description, + icon=icon_filename, url='/mldonkey/', + login_required=True, clients=clients, + allowed_groups=[group[0]]) self.add(shortcuts) firewall = Firewall('firewall-mldonkey', name, ports=['http', 'https'], diff --git a/plinth/modules/mldonkey/manifest.py b/plinth/modules/mldonkey/manifest.py index 969aed210..8151336cb 100644 --- a/plinth/modules/mldonkey/manifest.py +++ b/plinth/modules/mldonkey/manifest.py @@ -55,24 +55,18 @@ clients = validate([{ backup = validate_backup({ 'config': { 'files': [ - '/var/lib/mldonkey/bittorrent.ini', - '/var/lib/mldonkey/bt_dht.ini', + '/var/lib/mldonkey/bittorrent.ini', '/var/lib/mldonkey/bt_dht.ini', '/var/lib/mldonkey/directconnect.ini', - '/var/lib/mldonkey/donkey.ini', - '/var/lib/mldonkey/downloads.ini', + '/var/lib/mldonkey/donkey.ini', '/var/lib/mldonkey/downloads.ini', '/var/lib/mldonkey/files.ini', '/var/lib/mldonkey/file_sources.ini', - '/var/lib/mldonkey/fileTP.ini', - '/var/lib/mldonkey/friends.ini', - '/var/lib/mldonkey/searches.ini', - '/var/lib/mldonkey/servers.ini', + '/var/lib/mldonkey/fileTP.ini', '/var/lib/mldonkey/friends.ini', + '/var/lib/mldonkey/searches.ini', '/var/lib/mldonkey/servers.ini', '/var/lib/mldonkey/shared_files.ini', '/var/lib/mldonkey/shared_files_new.ini', '/var/lib/mldonkey/statistics.ini', - '/var/lib/mldonkey/stats_bt.ini', - '/var/lib/mldonkey/stats.ini', - '/var/lib/mldonkey/stats_mod.ini', - '/var/lib/mldonkey/users.ini' + '/var/lib/mldonkey/stats_bt.ini', '/var/lib/mldonkey/stats.ini', + '/var/lib/mldonkey/stats_mod.ini', '/var/lib/mldonkey/users.ini' ] }, 'services': ['mldonkey-server'] diff --git a/plinth/modules/mldonkey/urls.py b/plinth/modules/mldonkey/urls.py index 5b5e18483..8c9c9a28c 100644 --- a/plinth/modules/mldonkey/urls.py +++ b/plinth/modules/mldonkey/urls.py @@ -26,10 +26,10 @@ from plinth.views import AppView urlpatterns = [ url( r'^apps/mldonkey/$', - AppView.as_view( - app_id='mldonkey', name=mldonkey.name, - diagnostics_module_name='mldonkey', - description=mldonkey.description, clients=mldonkey.clients, - manual_page=mldonkey.manual_page, show_status_block=True), - name='index'), + AppView.as_view(app_id='mldonkey', name=mldonkey.name, + diagnostics_module_name='mldonkey', + description=mldonkey.description, + clients=mldonkey.clients, + manual_page=mldonkey.manual_page, + show_status_block=True), name='index'), ] diff --git a/plinth/modules/monkeysphere/urls.py b/plinth/modules/monkeysphere/urls.py index 86ad7ff14..ae8b554f4 100644 --- a/plinth/modules/monkeysphere/urls.py +++ b/plinth/modules/monkeysphere/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the monkeysphere module. """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^sys/monkeysphere/$', views.index, name='index'), url(r'^sys/monkeysphere/(?P[0-9A-Za-z:+/]+)/import/$', diff --git a/plinth/modules/mumble/manifest.py b/plinth/modules/mumble/manifest.py index 0ff16ea8f..132c1b74f 100644 --- a/plinth/modules/mumble/manifest.py +++ b/plinth/modules/mumble/manifest.py @@ -72,8 +72,4 @@ clients = validate([{ }] }]) -backup = validate_backup({ - 'data': { - 'directories': ['/var/lib/mumble-server'] - } -}) +backup = validate_backup({'data': {'directories': ['/var/lib/mumble-server']}}) diff --git a/plinth/modules/names/urls.py b/plinth/modules/names/urls.py index 607b4279f..29e6ba589 100644 --- a/plinth/modules/names/urls.py +++ b/plinth/modules/names/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the name services module """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^sys/names/$', views.index, name='index'), ] diff --git a/plinth/modules/networks/__init__.py b/plinth/modules/networks/__init__.py index dd630c3ce..9a0d0816e 100644 --- a/plinth/modules/networks/__init__.py +++ b/plinth/modules/networks/__init__.py @@ -84,10 +84,10 @@ def diagnose(): addresses = _get_interface_addresses(interfaces) for address in addresses: - results.append( - action_utils.diagnose_port_listening(53, 'tcp', address)) - results.append( - action_utils.diagnose_port_listening(53, 'udp', address)) + results.append(action_utils.diagnose_port_listening( + 53, 'tcp', address)) + results.append(action_utils.diagnose_port_listening( + 53, 'udp', address)) results.append(_diagnose_dnssec('4')) results.append(_diagnose_dnssec('6')) diff --git a/plinth/modules/networks/forms.py b/plinth/modules/networks/forms.py index 91cae9896..5cac3ab4c 100644 --- a/plinth/modules/networks/forms.py +++ b/plinth/modules/networks/forms.py @@ -34,17 +34,15 @@ class ConnectionTypeSelectForm(forms.Form): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['connection_type'].widget.attrs.update({ - 'autofocus': 'autofocus' - }) + self.fields['connection_type'].widget.attrs.update( + {'autofocus': 'autofocus'}) class ConnectionForm(forms.Form): """Base form to create/edit a connection.""" name = forms.CharField(label=_('Connection Name')) interface = forms.ChoiceField( - label=_('Physical Interface'), - choices=(), + label=_('Physical Interface'), choices=(), help_text=_('The network device that this connection should be bound ' 'to.')) zone = forms.ChoiceField( @@ -52,90 +50,70 @@ class ConnectionForm(forms.Form): help_text=_('The firewall zone will control which services are ' 'available over this interfaces. Select Internal only ' 'for trusted networks.'), - choices=[('external', _('External')), - ('internal', _('Internal'))]) + choices=[('external', _('External')), ('internal', _('Internal'))]) ipv4_method = forms.ChoiceField( - label=_('IPv4 Addressing Method'), - help_text=format_lazy( + label=_('IPv4 Addressing Method'), help_text=format_lazy( ugettext_lazy( '"Automatic" method will make {box_name} acquire ' 'configuration from this network making it a client. "Shared" ' 'method will make {box_name} act as a router, configure ' 'clients on this network and share its Internet connection.'), box_name=ugettext_lazy(cfg.box_name)), - choices=[('auto', _('Automatic (DHCP)')), - ('shared', _('Shared')), - ('manual', _('Manual')), - ('disabled', _('Disabled'))]) + choices=[('auto', _('Automatic (DHCP)')), ('shared', _('Shared')), + ('manual', _('Manual')), ('disabled', _('Disabled'))]) ipv4_address = forms.CharField( - label=_('Address'), - validators=[validators.validate_ipv4_address], + label=_('Address'), validators=[validators.validate_ipv4_address], required=False) ipv4_netmask = forms.CharField( label=_('Netmask'), help_text=_('Optional value. If left blank, a default netmask ' 'based on the address will be used.'), - validators=[validators.validate_ipv4_address], - required=False) + validators=[validators.validate_ipv4_address], required=False) ipv4_gateway = forms.CharField( - label=_('Gateway'), - help_text=_('Optional value.'), - validators=[validators.validate_ipv4_address], - required=False) + label=_('Gateway'), help_text=_('Optional value.'), + validators=[validators.validate_ipv4_address], required=False) ipv4_dns = forms.CharField( label=_('DNS Server'), help_text=_('Optional value. If this value is given and IPv4 ' 'addressing method is "Automatic", the DNS Servers ' 'provided by a DHCP server will be ignored.'), - validators=[validators.validate_ipv4_address], - required=False) + validators=[validators.validate_ipv4_address], required=False) ipv4_second_dns = forms.CharField( label=_('Second DNS Server'), help_text=_('Optional value. If this value is given and IPv4 ' 'Addressing Method is "Automatic", the DNS Servers ' 'provided by a DHCP server will be ignored.'), - validators=[validators.validate_ipv4_address], - required=False) + validators=[validators.validate_ipv4_address], required=False) ipv6_method = forms.ChoiceField( - label=_('IPv6 Addressing Method'), - help_text=format_lazy( + label=_('IPv6 Addressing Method'), help_text=format_lazy( ugettext_lazy( '"Automatic" methods will make {box_name} acquire ' 'configuration from this network making it a client.'), box_name=ugettext_lazy(cfg.box_name)), - choices=[('auto', _('Automatic')), - ('dhcp', _('Automatic, DHCP only')), - ('manual', _('Manual')), - ('ignore', _('Ignore'))]) + choices=[('auto', _('Automatic')), ('dhcp', _('Automatic, DHCP only')), + ('manual', _('Manual')), ('ignore', _('Ignore'))]) ipv6_address = forms.CharField( - label=_('Address'), - validators=[validators.validate_ipv6_address], - required=False) - ipv6_prefix = forms.IntegerField( - label=_('Prefix'), - help_text=_('Value between 1 and 128.'), - min_value=1, - max_value=128, + label=_('Address'), validators=[validators.validate_ipv6_address], required=False) + ipv6_prefix = forms.IntegerField(label=_('Prefix'), + help_text=_('Value between 1 and 128.'), + min_value=1, max_value=128, + required=False) ipv6_gateway = forms.CharField( - label=_('Gateway'), - help_text=_('Optional value.'), - validators=[validators.validate_ipv6_address], - required=False) + label=_('Gateway'), help_text=_('Optional value.'), + validators=[validators.validate_ipv6_address], required=False) ipv6_dns = forms.CharField( label=_('DNS Server'), help_text=_('Optional value. If this value is given and IPv6 ' 'addressing method is "Automatic", the DNS Servers ' 'provided by a DHCP server will be ignored.'), - validators=[validators.validate_ipv6_address], - required=False) + validators=[validators.validate_ipv6_address], required=False) ipv6_second_dns = forms.CharField( label=_('Second DNS Server'), help_text=_('Optional value. If this value is given and IPv6 ' 'Addressing Method is "Automatic", the DNS Servers ' 'provided by a DHCP server will be ignored.'), - validators=[validators.validate_ipv6_address], - required=False) + validators=[validators.validate_ipv6_address], required=False) @staticmethod def _get_interface_choices(device_type): @@ -143,8 +121,8 @@ class ConnectionForm(forms.Form): interfaces = network.get_interface_list(device_type) choices = [('', _('-- select --'))] for interface, mac in interfaces.items(): - display_string = '{interface} ({mac})'.format(interface=interface, - mac=mac) + display_string = '{interface} ({mac})'.format( + interface=interface, mac=mac) choices.append((interface, display_string)) return choices @@ -258,33 +236,29 @@ class PPPoEForm(EthernetForm): class WifiForm(ConnectionForm): """Form to create/edit a Wi-Fi connection.""" - field_order = ['name', 'interface', 'zone', 'ssid', 'mode', 'band', - 'channel', 'bssid', 'auth_mode', 'passphrase', - 'ipv4_method', 'ipv4_address', 'ipv4_netmask', - 'ipv4_gateway', 'ipv4_dns', 'ipv4_second_dns', - 'ipv6_method', 'ipv6_address', 'ipv6_prefix', - 'ipv6_gateway', 'ipv6_dns', 'ipv6_second_dns'] + field_order = [ + 'name', 'interface', 'zone', 'ssid', 'mode', 'band', 'channel', + 'bssid', 'auth_mode', 'passphrase', 'ipv4_method', 'ipv4_address', + 'ipv4_netmask', 'ipv4_gateway', 'ipv4_dns', 'ipv4_second_dns', + 'ipv6_method', 'ipv6_address', 'ipv6_prefix', 'ipv6_gateway', + 'ipv6_dns', 'ipv6_second_dns' + ] - ssid = forms.CharField( - label=_('SSID'), - help_text=_('The visible name of the network.')) + ssid = forms.CharField(label=_('SSID'), + help_text=_('The visible name of the network.')) mode = forms.ChoiceField( - label=_('Mode'), - choices=[('infrastructure', _('Infrastructure')), - ('ap', _('Access Point')), - ('adhoc', _('Ad-hoc'))]) + label=_('Mode'), choices=[('infrastructure', _('Infrastructure')), + ('ap', _('Access Point')), + ('adhoc', _('Ad-hoc'))]) band = forms.ChoiceField( - label=_('Frequency Band'), - choices=[('auto', _('Automatic')), - ('a', _('A (5 GHz)')), - ('bg', _('B/G (2.4 GHz)'))]) + label=_('Frequency Band'), choices=[('auto', _('Automatic')), + ('a', _('A (5 GHz)')), + ('bg', _('B/G (2.4 GHz)'))]) channel = forms.IntegerField( label=_('Channel'), help_text=_('Optional value. Wireless channel in the selected ' 'frequency band to restrict to. Blank or 0 value means ' - 'automatic selection.'), - min_value=0, - max_value=255, + 'automatic selection.'), min_value=0, max_value=255, required=False) bssid = forms.RegexField( label=_('BSSID'), @@ -292,18 +266,15 @@ class WifiForm(ConnectionForm): 'When connecting to an access point, connect only if the ' 'BSSID of the access point matches the one provided. ' 'Example: 00:11:22:aa:bb:cc.'), - regex=r'^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$', - required=False) + regex=r'^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$', required=False) auth_mode = forms.ChoiceField( label=_('Authentication Mode'), help_text=_('Select WPA if the wireless network is secured and \ requires clients to have the password to connect.'), - choices=[('wpa', _('WPA')), - ('open', _('Open'))]) - passphrase = forms.CharField( - label=_('Passphrase'), - validators=[validators.MinLengthValidator(8)], - required=False) + choices=[('wpa', _('WPA')), ('open', _('Open'))]) + passphrase = forms.CharField(label=_('Passphrase'), + validators=[validators.MinLengthValidator(8)], + required=False) def __init__(self, *args, **kwargs): """Initialize the form, populate interface choices.""" diff --git a/plinth/modules/networks/urls.py b/plinth/modules/networks/urls.py index 6e93f68f1..caab595d0 100644 --- a/plinth/modules/networks/urls.py +++ b/plinth/modules/networks/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the Network module """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import networks as views - urlpatterns = [ url(r'^sys/networks/$', views.index, name='index'), url(r'^sys/networks/(?P[\w.@+-]+)/show/$', views.show, name='show'), @@ -38,9 +36,9 @@ urlpatterns = [ url(r'^sys/networks/add/ethernet/$', views.add_ethernet, name='add_ethernet'), url(r'^sys/networks/add/pppoe/$', views.add_pppoe, name='add_pppoe'), - url(r'^sys/networks/add/wifi/(?:(?P[^/]+)/' - r'(?P[^/]+)/)?$', - views.add_wifi, name='add_wifi'), + url( + r'^sys/networks/add/wifi/(?:(?P[^/]+)/' + r'(?P[^/]+)/)?$', views.add_wifi, name='add_wifi'), url(r'^sys/networks/(?P[\w.@+-]+)/delete/$', views.delete, name='delete'), ] diff --git a/plinth/modules/openvpn/forms.py b/plinth/modules/openvpn/forms.py index c77b05ea7..e1da3cdf1 100644 --- a/plinth/modules/openvpn/forms.py +++ b/plinth/modules/openvpn/forms.py @@ -24,6 +24,5 @@ from django.utils.translation import ugettext_lazy as _ class OpenVpnForm(forms.Form): # pylint: disable=W0232 """OpenVPN configuration form.""" - enabled = forms.BooleanField( - label=_('Enable OpenVPN server'), - required=False) + enabled = forms.BooleanField(label=_('Enable OpenVPN server'), + required=False) diff --git a/plinth/modules/openvpn/urls.py b/plinth/modules/openvpn/urls.py index 356d23618..af647bebe 100644 --- a/plinth/modules/openvpn/urls.py +++ b/plinth/modules/openvpn/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the OpenVPN module. """ @@ -24,7 +23,6 @@ from django.conf.urls import url from plinth.utils import non_admin_view from . import views - urlpatterns = [ url(r'^apps/openvpn/$', views.index, name='index'), url(r'^apps/openvpn/setup/$', views.setup, name='setup'), diff --git a/plinth/modules/pagekite/tests/test_pagekite.py b/plinth/modules/pagekite/tests/test_pagekite.py index 46d0c387d..11a905dfc 100644 --- a/plinth/modules/pagekite/tests/test_pagekite.py +++ b/plinth/modules/pagekite/tests/test_pagekite.py @@ -14,36 +14,42 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Test modules for Pagekite functions. """ from plinth.modules.pagekite import utils - _tests = [ { 'line': 'https/8080:*.@kitename:localhost:8080:@kitesecret', - 'params': {'kitename': '*.@kitename', 'backend_host': 'localhost', - 'secret': '@kitesecret', 'protocol': 'https/8080', - 'backend_port': '8080'} + 'params': { + 'kitename': '*.@kitename', + 'backend_host': 'localhost', + 'secret': '@kitesecret', + 'protocol': 'https/8080', + 'backend_port': '8080' + } }, { 'line': 'https:*.@kitename:localhost:80:@kitesecret', - 'params': {'protocol': 'https', - 'kitename': '*.@kitename', - 'backend_port': '80', - 'backend_host': 'localhost', - 'secret': '@kitesecret'} + 'params': { + 'protocol': 'https', + 'kitename': '*.@kitename', + 'backend_port': '80', + 'backend_host': 'localhost', + 'secret': '@kitesecret' + } }, { 'line': 'raw/22:@kitename:localhost:22:@kitesecret', - 'params': {'protocol': 'raw/22', - 'kitename': '@kitename', - 'backend_port': '22', - 'backend_host': 'localhost', - 'secret': '@kitesecret'} + 'params': { + 'protocol': 'raw/22', + 'kitename': '@kitename', + 'backend_port': '22', + 'backend_host': 'localhost', + 'secret': '@kitesecret' + } }, ] diff --git a/plinth/modules/power/urls.py b/plinth/modules/power/urls.py index 859d40c3c..3292c8104 100644 --- a/plinth/modules/power/urls.py +++ b/plinth/modules/power/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the power module. """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^sys/power/$', views.index, name='index'), url(r'^sys/power/restart$', views.restart, name='restart'), diff --git a/plinth/modules/radicale/__init__.py b/plinth/modules/radicale/__init__.py index 6f02ff45c..d5bc72ca1 100644 --- a/plinth/modules/radicale/__init__.py +++ b/plinth/modules/radicale/__init__.py @@ -110,7 +110,6 @@ class RadicaleApp(app_module.App): class RadicaleWebserver(Webserver): """Webserver enable/disable behavior specific for radicale.""" - @property def web_name(self): """Return web configuration name based on radicale version.""" @@ -127,7 +126,6 @@ class RadicaleWebserver(Webserver): class RadicaleUwsgi(Uwsgi): """uWSGI enable/disable behavior specific for radicale.""" - def is_enabled(self): """Return whether the uWSGI configuration is enabled if version>=2.""" package_version = get_package_version() @@ -152,7 +150,6 @@ class RadicaleUwsgi(Uwsgi): class RadicaleDaemon(Daemon): """Daemon enable/disable behavior specific for radicale.""" - @staticmethod def _is_old_radicale(): """Return whether radicale is less than version 2.""" @@ -251,8 +248,8 @@ def disable(): def load_augeas(): """Prepares the augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # INI file lens aug.set('/augeas/load/Puppet/lens', 'Puppet.lns') diff --git a/plinth/modules/radicale/manifest.py b/plinth/modules/radicale/manifest.py index 883caebb4..7eafdc54c 100644 --- a/plinth/modules/radicale/manifest.py +++ b/plinth/modules/radicale/manifest.py @@ -87,8 +87,7 @@ clients = validate([{ 'name': 'evolution' }] }, { - 'name': - _('Radicale'), + 'name': _('Radicale'), 'platforms': [{ 'type': 'web', 'url': '/radicale/' diff --git a/plinth/modules/roundcube/__init__.py b/plinth/modules/roundcube/__init__.py index dd476f916..fe27df7d3 100644 --- a/plinth/modules/roundcube/__init__.py +++ b/plinth/modules/roundcube/__init__.py @@ -80,8 +80,7 @@ class RoundcubeApp(app_module.App): shortcut = frontpage.Shortcut('shortcut-roundcube', name, short_description=short_description, - icon=icon_filename, - url='/roundcube/', + icon=icon_filename, url='/roundcube/', clients=clients, login_required=True) self.add(shortcut) diff --git a/plinth/modules/searx/__init__.py b/plinth/modules/searx/__init__.py index 38c562a0e..98bb00189 100644 --- a/plinth/modules/searx/__init__.py +++ b/plinth/modules/searx/__init__.py @@ -29,7 +29,7 @@ from plinth.modules.apache.components import Uwsgi, Webserver from plinth.modules.firewall.components import Firewall from plinth.modules.users import register_group -from .manifest import PUBLIC_ACCESS_SETTING_FILE, backup, clients # noqa, pylint: disable=unused-import +from .manifest import PUBLIC_ACCESS_SETTING_FILE, backup, clients # noqa, pylint: disable=unused-import clients = clients @@ -99,7 +99,6 @@ class SearxApp(app_module.App): class SearxWebserverAuth(Webserver): """Component to handle Searx authentication webserver configuration.""" - def is_enabled(self): """Return if configuration is enabled or public access is enabled.""" return is_public_access_enabled() or super().is_enabled() diff --git a/plinth/modules/security/forms.py b/plinth/modules/security/forms.py index a5f791f4a..b87172c80 100644 --- a/plinth/modules/security/forms.py +++ b/plinth/modules/security/forms.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Forms for security module """ diff --git a/plinth/modules/security/manifest.py b/plinth/modules/security/manifest.py index 606e75da4..396019472 100644 --- a/plinth/modules/security/manifest.py +++ b/plinth/modules/security/manifest.py @@ -20,8 +20,7 @@ Application manifest for security. from plinth.modules.backups.api import validate as validate_backup -backup = validate_backup({ - 'config': { +backup = validate_backup( + {'config': { 'files': ['/etc/security/access.d/50freedombox.conf'] - } -}) + }}) diff --git a/plinth/modules/security/urls.py b/plinth/modules/security/urls.py index ffdd10c22..5dc728693 100644 --- a/plinth/modules/security/urls.py +++ b/plinth/modules/security/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the security module """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^sys/security/$', views.index, name='index'), url(r'^sys/security/report$', views.report, name='report'), diff --git a/plinth/modules/security/views.py b/plinth/modules/security/views.py index 3fbf5521b..9e44d786c 100644 --- a/plinth/modules/security/views.py +++ b/plinth/modules/security/views.py @@ -43,15 +43,11 @@ def index(request): else: form = SecurityForm(initial=status, prefix='security') - return TemplateResponse( - request, 'security.html', { - 'name': - _('Security'), - 'manual_page': - security.manual_page, - 'form': - form, - }) + return TemplateResponse(request, 'security.html', { + 'name': _('Security'), + 'manual_page': security.manual_page, + 'form': form, + }) def get_status(request): diff --git a/plinth/modules/shadowsocks/forms.py b/plinth/modules/shadowsocks/forms.py index 761a56cc2..6f143a328 100644 --- a/plinth/modules/shadowsocks/forms.py +++ b/plinth/modules/shadowsocks/forms.py @@ -39,7 +39,6 @@ METHODS = [('chacha20-ietf-poly1305', class TrimmedCharField(forms.CharField): """Trim the contents of a CharField""" - def clean(self, value): """Clean and validate the field value""" if value: @@ -50,12 +49,12 @@ class TrimmedCharField(forms.CharField): class ShadowsocksForm(AppForm): """Shadowsocks configuration form""" - server = TrimmedCharField( - label=_('Server'), help_text=_('Server hostname or IP address')) + server = TrimmedCharField(label=_('Server'), + help_text=_('Server hostname or IP address')) - server_port = forms.IntegerField( - label=_('Server port'), min_value=0, max_value=65535, - help_text=_('Server port number')) + server_port = forms.IntegerField(label=_('Server port'), min_value=0, + max_value=65535, + help_text=_('Server port number')) password = forms.CharField( label=_('Password'), help_text=_('Password used to encrypt data. ' diff --git a/plinth/modules/snapshot/__init__.py b/plinth/modules/snapshot/__init__.py index 5587035f3..82501aa0f 100644 --- a/plinth/modules/snapshot/__init__.py +++ b/plinth/modules/snapshot/__init__.py @@ -100,8 +100,8 @@ def setup(helper, old_version=None): def load_augeas(): """Initialize Augeas.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # shell-script config file lens aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns') diff --git a/plinth/modules/snapshot/forms.py b/plinth/modules/snapshot/forms.py index 277096ecf..ae92c6806 100644 --- a/plinth/modules/snapshot/forms.py +++ b/plinth/modules/snapshot/forms.py @@ -38,9 +38,10 @@ class SnapshotForm(forms.Form): choices=[('yes', 'Enabled'), ('no', 'Disabled')]) enable_software_snapshots = forms.ChoiceField( - label=_('Software Installation Snapshots'), help_text=_( - 'Enable or disable snapshots before and after software ' - 'installation'), choices=[('yes', 'Enabled'), ('no', 'Disabled')]) + label=_('Software Installation Snapshots'), + help_text=_('Enable or disable snapshots before and after software ' + 'installation'), choices=[('yes', 'Enabled'), + ('no', 'Disabled')]) hourly_limit = forms.IntegerField( label=_('Hourly Snapshots Limit'), min_value=0, diff --git a/plinth/modules/snapshot/views.py b/plinth/modules/snapshot/views.py index cf0b11fea..92f303c7c 100644 --- a/plinth/modules/snapshot/views.py +++ b/plinth/modules/snapshot/views.py @@ -121,7 +121,6 @@ def manage(request): def update_configuration(request, old_status, new_status): """Update configuration of snapshots.""" - def make_config(args): key, stamp = args[0], args[1] if old_status[key] != new_status[key]: @@ -158,8 +157,9 @@ def update_configuration(request, old_status, new_status): except ActionError as exception: messages.error( request, - _('Action error: {0} [{1}] [{2}]').format( - exception.args[0], exception.args[1], exception.args[2])) + _('Action error: {0} [{1}] [{2}]').format(exception.args[0], + exception.args[1], + exception.args[2])) def delete_selected(request): diff --git a/plinth/modules/ssh/manifest.py b/plinth/modules/ssh/manifest.py index 0391f5a76..0f3cd172e 100644 --- a/plinth/modules/ssh/manifest.py +++ b/plinth/modules/ssh/manifest.py @@ -23,11 +23,9 @@ from plinth.modules.backups.api import validate as validate_backup backup = validate_backup({ 'secrets': { 'files': [ - '/etc/ssh/ssh_host_ecdsa_key', - '/etc/ssh/ssh_host_ecdsa_key.pub', + '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ecdsa_key.pub', '/etc/ssh/ssh_host_ed25519_key', - '/etc/ssh/ssh_host_ed25519_key.pub', - '/etc/ssh/ssh_host_rsa_key', + '/etc/ssh/ssh_host_ed25519_key.pub', '/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_rsa_key.pub' ] } diff --git a/plinth/modules/sso/__init__.py b/plinth/modules/sso/__init__.py index 88d3200ed..3e3bef6f1 100644 --- a/plinth/modules/sso/__init__.py +++ b/plinth/modules/sso/__init__.py @@ -30,7 +30,10 @@ depends = ['security', 'apache'] name = _('Single Sign On') managed_packages = [ - 'libapache2-mod-auth-pubtkt', 'openssl', 'python3-openssl', 'flite', + 'libapache2-mod-auth-pubtkt', + 'openssl', + 'python3-openssl', + 'flite', ] diff --git a/plinth/modules/sso/urls.py b/plinth/modules/sso/urls.py index 89ca2ec2f..5bad3db8e 100644 --- a/plinth/modules/sso/urls.py +++ b/plinth/modules/sso/urls.py @@ -25,8 +25,8 @@ from stronghold.decorators import public from plinth.utils import non_admin_view urlpatterns = [ - url(r'^accounts/sso/login/$', - public(SSOLoginView.as_view()), name='sso-login'), + url(r'^accounts/sso/login/$', public(SSOLoginView.as_view()), + name='sso-login'), url(r'^accounts/sso/refresh/$', non_admin_view(refresh), name='sso-refresh'), ] diff --git a/plinth/modules/sso/views.py b/plinth/modules/sso/views.py index ef3c98aa0..7991a0581 100644 --- a/plinth/modules/sso/views.py +++ b/plinth/modules/sso/views.py @@ -82,8 +82,8 @@ class CaptchaLoginView(LoginView): form_class = AuthenticationForm def dispatch(self, request, *args, **kwargs): - response = super(CaptchaLoginView, self).dispatch( - request, *args, **kwargs) + response = super(CaptchaLoginView, + self).dispatch(request, *args, **kwargs) if not request.POST: return response diff --git a/plinth/modules/storage/__init__.py b/plinth/modules/storage/__init__.py index 311d271dc..8605d7c6e 100644 --- a/plinth/modules/storage/__init__.py +++ b/plinth/modules/storage/__init__.py @@ -193,8 +193,9 @@ def is_expandable(device): return False try: - output = actions.superuser_run( - 'storage', ['is-partition-expandable', device], log_error=False) + output = actions.superuser_run('storage', + ['is-partition-expandable', device], + log_error=False) except actions.ActionError: return False diff --git a/plinth/modules/storage/tests/test_storage.py b/plinth/modules/storage/tests/test_storage.py index 0fab834f5..4edeec01e 100644 --- a/plinth/modules/storage/tests/test_storage.py +++ b/plinth/modules/storage/tests/test_storage.py @@ -36,7 +36,6 @@ def _get_partition_device(device, partition_number): class Disk(): """Context manager to create/destroy a disk.""" - def __init__(self, test_case, size, disk_info, file_system_info=None): """Initialize the context manager object.""" self.size = size @@ -120,7 +119,6 @@ class Disk(): class TestActions: """Test all actions related to storage.""" - @pytest.mark.usefixtures('needs_root') def test_simple_case(self): """Test a simple with no complications""" diff --git a/plinth/modules/syncthing/urls.py b/plinth/modules/syncthing/urls.py index 63a7bee1e..9cf71bdad 100644 --- a/plinth/modules/syncthing/urls.py +++ b/plinth/modules/syncthing/urls.py @@ -26,10 +26,10 @@ from plinth.views import AppView urlpatterns = [ url( r'^apps/syncthing/$', - AppView.as_view( - app_id='syncthing', name=syncthing.name, - diagnostics_module_name='syncthing', - description=syncthing.description, clients=syncthing.clients, - manual_page=syncthing.manual_page, show_status_block=True), - name='index'), + AppView.as_view(app_id='syncthing', name=syncthing.name, + diagnostics_module_name='syncthing', + description=syncthing.description, + clients=syncthing.clients, + manual_page=syncthing.manual_page, + show_status_block=True), name='index'), ] diff --git a/plinth/modules/tahoe/__init__.py b/plinth/modules/tahoe/__init__.py index 9983845b1..bae49c55d 100644 --- a/plinth/modules/tahoe/__init__.py +++ b/plinth/modules/tahoe/__init__.py @@ -76,9 +76,10 @@ class TahoeApp(app_module.App): parent_url_name='apps', advanced=True) self.add(menu_item) - shortcut = frontpage.Shortcut( - 'shortcut-tahoe', name, short_description=short_description, - icon=icon_filename, url=None, login_required=True) + shortcut = frontpage.Shortcut('shortcut-tahoe', name, + short_description=short_description, + icon=icon_filename, url=None, + login_required=True) self.add(shortcut) firewall = Firewall('firewall-tahoe', name, ports=['tahoe-plinth'], @@ -94,7 +95,6 @@ class TahoeApp(app_module.App): class Shortcut(frontpage.Shortcut): """Frontpage shortcut to use configured domain name for URL.""" - def enable(self): """Set the proper shortcut URL when enabled.""" super().enable() diff --git a/plinth/modules/tahoe/errors.py b/plinth/modules/tahoe/errors.py index c25de0279..9fff21e6a 100644 --- a/plinth/modules/tahoe/errors.py +++ b/plinth/modules/tahoe/errors.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Errors for Tahoe-LAFS module """ diff --git a/plinth/modules/tor/forms.py b/plinth/modules/tor/forms.py index 41a38807c..00dab52c9 100644 --- a/plinth/modules/tor/forms.py +++ b/plinth/modules/tor/forms.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Forms for configuring Tor. """ @@ -86,55 +85,44 @@ def bridges_validator(bridges): class TorForm(forms.Form): # pylint: disable=W0232 """Tor configuration form.""" - enabled = forms.BooleanField( - label=_('Enable Tor'), - required=False) + enabled = forms.BooleanField(label=_('Enable Tor'), required=False) use_upstream_bridges = forms.BooleanField( label=_('Use upstream bridges to connect to Tor network'), - required=False, - help_text=_( + required=False, help_text=_( 'When enabled, the bridges configured below will be used to ' 'connect to the Tor network. Use this option if your Internet ' 'Service Provider (ISP) blocks or censors connections to the ' 'Tor Network. This will disable relay modes.')) upstream_bridges = TrimmedCharField( - widget=widgets.Textarea, - label=_('Upstream bridges'), - required=False, + widget=widgets.Textarea, label=_('Upstream bridges'), required=False, help_text=_( 'You can get some bridges from ' 'https://bridges.torproject.org/ and copy/paste the bridge ' 'information here. Currently supported transports are none, ' - 'obfs3, obfs4 and scamblesuit.'), - validators=[bridges_validator]) + 'obfs3, obfs4 and scamblesuit.'), validators=[bridges_validator]) relay_enabled = forms.BooleanField( - label=_('Enable Tor relay'), - required=False, - help_text=format_lazy(_( - 'When enabled, your {box_name} will run a Tor relay and donate ' - 'bandwidth to the Tor network. Do this if you have more than ' - '2 megabits/s of upload and download bandwidth.'), - box_name=_(cfg.box_name))) + label=_('Enable Tor relay'), required=False, help_text=format_lazy( + _('When enabled, your {box_name} will run a Tor relay and donate ' + 'bandwidth to the Tor network. Do this if you have more than ' + '2 megabits/s of upload and download bandwidth.'), + box_name=_(cfg.box_name))) bridge_relay_enabled = forms.BooleanField( - label=_('Enable Tor bridge relay'), - required=False, - help_text=format_lazy(_( - 'When enabled, relay information is published in the Tor bridge ' - 'database instead of public Tor relay database making it harder ' - 'to censor this node. This helps others circumvent censorship.'), - box_name=_(cfg.box_name))) + label=_('Enable Tor bridge relay'), required=False, + help_text=format_lazy( + _('When enabled, relay information is published in the Tor bridge ' + 'database instead of public Tor relay database making it harder ' + 'to censor this node. This helps others circumvent censorship.'), + box_name=_(cfg.box_name))) hs_enabled = forms.BooleanField( - label=_('Enable Tor Onion Service'), - required=False, - help_text=format_lazy(_( - 'An onion service will allow {box_name} to provide selected ' - 'services (such as wiki or chat) without revealing its ' - 'location. Do not use this for strong anonymity yet.'), - box_name=_(cfg.box_name))) + label=_('Enable Tor Hidden Service'), required=False, + help_text=format_lazy( + _('A hidden service will allow {box_name} to provide selected ' + 'services (such as wiki or chat) without revealing its ' + 'location. Do not use this for strong anonymity yet.'), + box_name=_(cfg.box_name))) apt_transport_tor_enabled = forms.BooleanField( - label=_('Download software packages over Tor'), - required=False, + label=_('Download software packages over Tor'), required=False, help_text=_('When enabled, software will be downloaded over the Tor ' 'network for installations and upgrades. This adds a ' 'degree of privacy and security during software ' @@ -147,8 +135,10 @@ class TorForm(forms.Form): # pylint: disable=W0232 upstream_bridges = cleaned_data.get('upstream_bridges') if use_upstream_bridges and not upstream_bridges: - self.add_error('upstream_bridges', ValidationError(_( - 'Specify at least one upstream bridge to use upstream ' - 'bridges.'), code='invalid')) + self.add_error( + 'upstream_bridges', + ValidationError( + _('Specify at least one upstream bridge to use upstream ' + 'bridges.'), code='invalid')) return cleaned_data diff --git a/plinth/modules/tor/tests/test_tor.py b/plinth/modules/tor/tests/test_tor.py index 1226f52af..50eba1839 100644 --- a/plinth/modules/tor/tests/test_tor.py +++ b/plinth/modules/tor/tests/test_tor.py @@ -28,7 +28,6 @@ from plinth.modules.tor import forms, utils class TestTor: """Test cases for testing the Tor module.""" - @staticmethod @pytest.mark.usefixtures('needs_root') def test_is_apt_transport_tor_enabled(): @@ -51,7 +50,6 @@ class TestTor: class TestTorForm: """Test whether Tor configration form works.""" - @staticmethod def test_bridge_validator(): """Test upstream bridges' form field validator.""" diff --git a/plinth/modules/tor/urls.py b/plinth/modules/tor/urls.py index 2a14d19a4..28ce8bed9 100644 --- a/plinth/modules/tor/urls.py +++ b/plinth/modules/tor/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the Tor module. """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^apps/tor/$', views.index, name='index'), ] diff --git a/plinth/modules/tor/utils.py b/plinth/modules/tor/utils.py index 4b6b04b08..0c721214b 100644 --- a/plinth/modules/tor/utils.py +++ b/plinth/modules/tor/utils.py @@ -104,8 +104,8 @@ def get_real_apt_uri_path(aug, path): def get_augeas(): """Return an instance of Augeaus for processing APT configuration.""" - aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Aptsources/lens', 'Aptsources.lns') aug.set('/augeas/load/Aptsources/incl[last() + 1]', '/etc/apt/sources.list') diff --git a/plinth/modules/transmission/views.py b/plinth/modules/transmission/views.py index 4a7a73edb..ab90cba45 100644 --- a/plinth/modules/transmission/views.py +++ b/plinth/modules/transmission/views.py @@ -50,9 +50,7 @@ class TransmissionAppView(views.AppView): ['get-configuration']) configuration = json.loads(configuration) status.update({ - key.translate(str.maketrans({ - '-': '_' - })): value + key.translate(str.maketrans({'-': '_'})): value for key, value in configuration.items() }) status['hostname'] = socket.gethostname() diff --git a/plinth/modules/upgrades/manifest.py b/plinth/modules/upgrades/manifest.py index f3fe5eb46..c1d95923c 100644 --- a/plinth/modules/upgrades/manifest.py +++ b/plinth/modules/upgrades/manifest.py @@ -20,8 +20,7 @@ Application manifest for upgrades. from plinth.modules.backups.api import validate as validate_backup -backup = validate_backup({ - 'config': { +backup = validate_backup( + {'config': { 'files': ['/etc/apt/apt.conf.d/20auto-upgrades'] - } -}) + }}) diff --git a/plinth/modules/upgrades/urls.py b/plinth/modules/upgrades/urls.py index 070651f7f..685a22295 100644 --- a/plinth/modules/upgrades/urls.py +++ b/plinth/modules/upgrades/urls.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ URLs for the upgrades module """ @@ -23,7 +22,6 @@ from django.conf.urls import url from . import views - urlpatterns = [ url(r'^sys/upgrades/$', views.UpgradesConfigurationView.as_view(), name='index'), diff --git a/plinth/modules/users/forms.py b/plinth/modules/users/forms.py index 8f81b0d59..0d415a95a 100644 --- a/plinth/modules/users/forms.py +++ b/plinth/modules/users/forms.py @@ -47,14 +47,13 @@ def get_group_choices(): class ValidNewUsernameCheckMixin(object): """Mixin to check if a username is valid for created new user.""" - def clean_username(self): """Check for username collisions with system users.""" username = self.cleaned_data['username'] if self.instance.username != username and \ not self.is_valid_new_username(): - raise ValidationError( - _('Username is taken or is reserved.'), code='invalid') + raise ValidationError(_('Username is taken or is reserved.'), + code='invalid') return username @@ -147,10 +146,8 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, plinth.forms.LanguageSelectionFormMixin, forms.ModelForm): """When user info is changed, also updates LDAP user.""" ssh_keys = forms.CharField( - label=ugettext_lazy('Authorized SSH Keys'), - required=False, - widget=forms.Textarea, - help_text=ugettext_lazy( + label=ugettext_lazy('Authorized SSH Keys'), required=False, + widget=forms.Textarea, help_text=ugettext_lazy( 'Setting an SSH public key will allow this user to ' 'securely log in to the system without using a ' 'password. You may enter multiple keys, one on each ' @@ -283,14 +280,12 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, class UserChangePasswordForm(SetPasswordForm): """Custom form that also updates password for LDAP users.""" - def __init__(self, request, *args, **kwargs): """Initialize the form with extra request argument.""" self.request = request super(UserChangePasswordForm, self).__init__(*args, **kwargs) - self.fields['new_password1'].widget.attrs.update({ - 'autofocus': 'autofocus' - }) + self.fields['new_password1'].widget.attrs.update( + {'autofocus': 'autofocus'}) def save(self, commit=True): """Save the user model and change LDAP password as well.""" @@ -310,7 +305,6 @@ class UserChangePasswordForm(SetPasswordForm): class FirstBootForm(ValidNewUsernameCheckMixin, auth.forms.UserCreationForm): """User module first boot step: create a new admin user.""" - def __init__(self, *args, **kwargs): self.request = kwargs.pop('request') super().__init__(*args, **kwargs) diff --git a/plinth/modules/users/tests/test_actions.py b/plinth/modules/users/tests/test_actions.py index 72dda8cc8..7ad3f60e0 100644 --- a/plinth/modules/users/tests/test_actions.py +++ b/plinth/modules/users/tests/test_actions.py @@ -81,8 +81,8 @@ def _try_login_to_ssh(username, password, returncode=0): def _action_file(): """Return the path to the 'users' actions file.""" current_directory = pathlib.Path(__file__).parent - return str( - current_directory / '..' / '..' / '..' / '..' / 'actions' / 'users') + return str(current_directory / '..' / '..' / '..' / '..' / 'actions' / + 'users') @pytest.fixture(name='disable_restricted_access', autouse=True) diff --git a/plinth/modules/users/views.py b/plinth/modules/users/views.py index 284b1ab90..f2696bb3c 100644 --- a/plinth/modules/users/views.py +++ b/plinth/modules/users/views.py @@ -40,7 +40,6 @@ from .forms import (CreateUserForm, FirstBootForm, UserChangePasswordForm, class ContextMixin(object): """Mixin to add 'title' to the template context.""" - def get_context_data(self, **kwargs): """Add self.title to template context.""" context = super(ContextMixin, self).get_context_data(**kwargs) diff --git a/plinth/network.py b/plinth/network.py index a5048444a..e45e3867d 100644 --- a/plinth/network.py +++ b/plinth/network.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Helper functions for working with network manager. """ @@ -103,9 +102,8 @@ def get_status_from_connection(connection): primary_connection = nm.Client.new(None).get_primary_connection() status['primary'] = ( - primary_connection and - primary_connection.get_uuid() == connection.get_uuid() - ) + primary_connection + and primary_connection.get_uuid() == connection.get_uuid()) return status @@ -131,18 +129,20 @@ def get_status_from_device(device): ip4_config = device.get_ip4_config() if ip4_config: addresses = ip4_config.get_addresses() - status['ip4']['addresses'] = [{'address': address.get_address(), - 'prefix': address.get_prefix()} - for address in addresses] + status['ip4']['addresses'] = [{ + 'address': address.get_address(), + 'prefix': address.get_prefix() + } for address in addresses] status['ip4']['gateway'] = ip4_config.get_gateway() status['ip4']['nameservers'] = ip4_config.get_nameservers() ip6_config = device.get_ip6_config() if ip6_config: addresses = ip6_config.get_addresses() - status['ip6']['addresses'] = [{'address': address.get_address(), - 'prefix': address.get_prefix()} - for address in addresses] + status['ip6']['addresses'] = [{ + 'address': address.get_address(), + 'prefix': address.get_prefix() + } for address in addresses] status['ip6']['gateway'] = ip6_config.get_gateway() status['ip6']['nameservers'] = ip6_config.get_nameservers() @@ -188,8 +188,19 @@ def _get_wifi_channel_from_frequency(frequency): # channel numbers. Search for a better solution! Even 5GHz is # not included yet. Only the plain frequency will show up on 5GHz # AP's. - channel_map = {2412: 1, 2417: 2, 2422: 3, 2427: 4, 2432: 5, 2437: 6, - 2442: 7, 2447: 8, 2452: 9, 2457: 10, 2462: 11} + channel_map = { + 2412: 1, + 2417: 2, + 2422: 3, + 2427: 4, + 2432: 5, + 2437: 6, + 2442: 7, + 2447: 8, + 2452: 9, + 2457: 10, + 2462: 11 + } try: return channel_map[frequency] except KeyError: @@ -207,8 +218,8 @@ def get_connection_list(): for connection in client.get_connections(): # Display a friendly type name if known. connection_type = connection.get_connection_type() - connection_type_name = CONNECTION_TYPE_NAMES.get(connection_type, - connection_type) + connection_type_name = CONNECTION_TYPE_NAMES.get( + connection_type, connection_type) settings_connection = connection.get_setting_connection() zone = settings_connection.get_zone() @@ -250,8 +261,10 @@ def get_active_connection(connection_uuid): found. """ connections = nm.Client.new(None).get_active_connections() - connections = {connection.get_uuid(): connection - for connection in connections} + connections = { + connection.get_uuid(): connection + for connection in connections + } try: return connections[connection_uuid] except KeyError: @@ -458,8 +471,8 @@ def activate_connection(connection_uuid): client = nm.Client.new(None) for device in client.get_devices(): if device.get_iface() == interface: - client.activate_connection_async( - connection, device, '/', None, _callback, None) + client.activate_connection_async(connection, device, '/', None, + _callback, None) break else: raise DeviceNotFound(connection) @@ -502,6 +515,7 @@ def wifi_scan(): access_points.append({ 'interface_name': device.get_iface(), 'ssid': ssid_string, - 'strength': access_point.get_strength()}) + 'strength': access_point.get_strength() + }) return access_points diff --git a/plinth/package.py b/plinth/package.py index a278a57dd..d2dd81d62 100644 --- a/plinth/package.py +++ b/plinth/package.py @@ -32,7 +32,6 @@ logger = logging.getLogger(__name__) class PackageException(Exception): """A package operation has failed.""" - def __init__(self, error_string=None, error_details=None, *args, **kwargs): """Store apt-get error string and details.""" super(PackageException, self).__init__(*args, **kwargs) @@ -48,7 +47,6 @@ class PackageException(Exception): class Transaction(object): """Information about an ongoing transaction.""" - def __init__(self, module_name, package_names): """Initialize transaction object. diff --git a/plinth/setup.py b/plinth/setup.py index 4b0897e9f..42b27636d 100644 --- a/plinth/setup.py +++ b/plinth/setup.py @@ -43,7 +43,6 @@ _force_upgrader = None class Helper(object): """Helper routines for modules to show progress.""" - def __init__(self, module_name, module): """Initialize the object.""" self.module_name = module_name @@ -421,11 +420,9 @@ class ForceUpgrader(): class TemporaryFailure(Exception): """Raised when upgrade fails but can be tried again immediately.""" - class PermanentFailure(Exception): """Raised when upgrade fails and there is nothing more we wish to do. """ - def __init__(self): """Initialize the force upgrader.""" if plinth.cfg.develop: diff --git a/plinth/tests/test_context_processors.py b/plinth/tests/test_context_processors.py index 146f61ec4..d2782bd0e 100644 --- a/plinth/tests/test_context_processors.py +++ b/plinth/tests/test_context_processors.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Test module for custom context processors. """ @@ -37,7 +36,7 @@ def fixture_menu(): def test_common(): """Verify that the common() function returns the correct values.""" - cfg.read() # initialize config settings + cfg.read() # initialize config settings request = HttpRequest() request.path = '/aaa/bbb/ccc/' diff --git a/plinth/tests/test_custom_shortcuts.py b/plinth/tests/test_custom_shortcuts.py index c0aaae145..5b860d03d 100644 --- a/plinth/tests/test_custom_shortcuts.py +++ b/plinth/tests/test_custom_shortcuts.py @@ -65,8 +65,8 @@ def test_shortcuts_api_with_empty_custom_shortcuts_list(): def test_shortcuts_api_with_custom_nextcloud_shortcut(): shortcuts = get_shortcuts_as_json() assert len(shortcuts['shortcuts']) >= 1 - assert any( - shortcut['name'] == 'NextCloud' for shortcut in shortcuts['shortcuts']) + assert any(shortcut['name'] == 'NextCloud' + for shortcut in shortcuts['shortcuts']) @pytest.mark.usefixtures('nextcloud_shortcut') diff --git a/plinth/tests/test_kvstore.py b/plinth/tests/test_kvstore.py index 4f1792a89..81973b3db 100644 --- a/plinth/tests/test_kvstore.py +++ b/plinth/tests/test_kvstore.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Test module for key/value store. """ @@ -38,8 +37,15 @@ def test_get_set(): def test_get_set_complex_structures(): """Verify that complex structures can be stored and retrieved.""" key = 'compex_structure' - expected_value = {'k1': 1, 'k2': [2, 3], 'k3': 4.5, 'k4': 'Hello', - 'k5': {'a': 'b'}} + expected_value = { + 'k1': 1, + 'k2': [2, 3], + 'k3': 4.5, + 'k4': 'Hello', + 'k5': { + 'a': 'b' + } + } kvstore.set(key, expected_value) actual_value = kvstore.get(key) assert expected_value == actual_value diff --git a/plinth/tests/test_middleware.py b/plinth/tests/test_middleware.py index 31a88275a..bb98a0814 100644 --- a/plinth/tests/test_middleware.py +++ b/plinth/tests/test_middleware.py @@ -42,7 +42,6 @@ def fixture_kwargs(): class TestSetupMiddleware: """Test cases for setup middleware.""" - @staticmethod @pytest.fixture(name='middleware') def fixture_middleware(load_cfg): @@ -135,7 +134,6 @@ class TestSetupMiddleware: class TestAdminMiddleware: """Test cases for admin middleware.""" - @staticmethod @pytest.fixture(name='middleware') def fixture_middleware(load_cfg): diff --git a/plinth/tests/test_network.py b/plinth/tests/test_network.py index ba772eb04..e417f6967 100644 --- a/plinth/tests/test_network.py +++ b/plinth/tests/test_network.py @@ -14,7 +14,6 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # - """ Test module for network configuration utilities. """ diff --git a/plinth/tests/test_templatetags.py b/plinth/tests/test_templatetags.py index 45bfc8396..4326a4422 100644 --- a/plinth/tests/test_templatetags.py +++ b/plinth/tests/test_templatetags.py @@ -51,9 +51,9 @@ def test_highlighting(): 'text': 'create' }] - tests = [['/abc/123/crunch/new/', '/abc/123/crunch/'], [ - '/abc/123/create/', '/abc/123/create/' - ], ['/abc/123/nolink/', '/abc/123/'], ['/abc/123/abx/', '/abc/123/'], + tests = [['/abc/123/crunch/new/', '/abc/123/crunch/'], + ['/abc/123/create/', '/abc/123/create/'], + ['/abc/123/nolink/', '/abc/123/'], ['/abc/123/abx/', '/abc/123/'], ['/abc/123/ab/', '/abc/123/'], ['/abc/123/', '/abc/123/']] for check_path, expected_active_path in tests: diff --git a/plinth/tests/test_utils.py b/plinth/tests/test_utils.py index 611319515..af4373f32 100644 --- a/plinth/tests/test_utils.py +++ b/plinth/tests/test_utils.py @@ -30,7 +30,6 @@ from plinth.utils import YAMLFile, is_user_admin class TestIsAdminUser: """Test class for is_user_admin utility.""" - @staticmethod @pytest.fixture(name='web_request') def fixture_web_request(): @@ -113,9 +112,7 @@ class TestYAMLFileUtil: with open(test_file.name, 'w') as conf_file: conf_file.write( - ruamel.yaml.round_trip_dump({ - 'property1': self.kv_pair - })) + ruamel.yaml.round_trip_dump({'property1': self.kv_pair})) with YAMLFile(test_file.name) as file_conf: file_conf['property2'] = self.kv_pair diff --git a/plinth/urls.py b/plinth/urls.py index 07be6c566..cebaeec82 100644 --- a/plinth/urls.py +++ b/plinth/urls.py @@ -27,8 +27,9 @@ from . import views urlpatterns = [ url(r'^$', views.index, name='index'), - url(r'^language-selection/$', public( - views.LanguageSelectionView.as_view()), name='language-selection'), + url(r'^language-selection/$', + public(views.LanguageSelectionView.as_view()), + name='language-selection'), url(r'^apps/$', views.AppsIndexView.as_view(), name='apps'), url(r'^sys/$', views.system_index, name='system'), diff --git a/plinth/web_framework.py b/plinth/web_framework.py index a3a01d885..45118ce5b 100644 --- a/plinth/web_framework.py +++ b/plinth/web_framework.py @@ -179,7 +179,6 @@ def get_languages(): Add additional languages that FreedomBox support but Django doesn't. """ - def gettext_noop(string): """Django's actual translation methods need Django to be setup.""" return string diff --git a/setup.py b/setup.py index 01cd31791..136197592 100755 --- a/setup.py +++ b/setup.py @@ -118,7 +118,6 @@ class CustomBuild(build): class CustomClean(clean): """Override clean command to clean doc, locales, and egg-info.""" - def run(self): """Execute clean command""" subprocess.check_call(['rm', '-rf', 'Plinth.egg-info/']) @@ -136,7 +135,6 @@ class CustomClean(clean): class CustomInstall(install): """Override install command.""" - def run(self): log.info("Removing disabled apps") for app in DISABLED_APPS_TO_REMOVE: @@ -149,7 +147,6 @@ class CustomInstall(install): class CustomInstallData(install_data): """Override install command to allow directory creation and copy""" - def _run_doc_install(self): """Install documentation""" command = ['make', '-j', '8', '-C', 'doc', 'install'] @@ -315,8 +312,8 @@ setuptools.setup( }, exclude_package_data={'': ['*/data/*']}, data_files=_gather_data_files() + - [('/usr/share/plinth/actions', glob.glob( - os.path.join('actions', '[a-z]*'))), + [('/usr/share/plinth/actions', glob.glob(os.path.join('actions', + '[a-z]*'))), ('/usr/share/man/man1', ['doc/plinth.1'])], cmdclass={ 'install': CustomInstall, diff --git a/vagrant-scripts/plinth-user-permissions.py b/vagrant-scripts/plinth-user-permissions.py index 4fe8991fc..bca08d1c6 100755 --- a/vagrant-scripts/plinth-user-permissions.py +++ b/vagrant-scripts/plinth-user-permissions.py @@ -24,8 +24,8 @@ environment. import augeas sudoers_file = '/etc/sudoers.d/plinth' -aug = augeas.Augeas( - flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) +aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) # lens for shell-script config file aug.set('/augeas/load/Shellvars/lens', 'Sudoers.lns')