diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b11199c70..11b5f5a42 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,7 +16,7 @@ code-quality: stage: test needs: [] script: - - python3 -m flake8 --exclude actions/domainname-change,actions/dynamicdns,actions/hostname-change,actions/networks container plinth actions/* + - python3 -m flake8 container plinth actions/* unit-tests: stage: test diff --git a/Vagrantfile b/Vagrantfile index e7566016e..3d518b5f0 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -16,7 +16,7 @@ Vagrant.configure(2) do |config| end config.vm.provision "shell", run: 'always', inline: <<-SHELL # Disable automatic upgrades - /vagrant/actions/upgrades disable-auto + echo -e 'APT::Periodic::Update-Package-Lists "0";\nAPT::Periodic::Unattended-Upgrade "0";' > //etc/apt/apt.conf.d/20auto-upgrades # Do not run system plinth systemctl stop plinth systemctl disable plinth diff --git a/actions/actions b/actions/actions index 1cebe5eae..e012b4b3c 100755 --- a/actions/actions +++ b/actions/actions @@ -8,6 +8,7 @@ import json import logging import os import sys +import traceback import typing import plinth.log @@ -26,16 +27,25 @@ def main(): parser = argparse.ArgumentParser() parser.add_argument('module', help='Module to trigger action in') parser.add_argument('action', help='Action to trigger in module') + parser.add_argument('--write-fd', type=int, default=1, + help='File descriptor to write output to') + parser.add_argument('--no-args', default=False, action='store_true', + help='Do not read arguments from stdin') args = parser.parse_args() try: try: - arguments = json.loads(sys.stdin.read()) + arguments = {'args': [], 'kwargs': {}} + if not args.no_args: + input_ = sys.stdin.read() + if input_: + arguments = json.loads(input_) except json.JSONDecodeError as exception: raise SyntaxError('Arguments on stdin not JSON.') from exception return_value = _call(args.module, args.action, arguments) - print(json.dumps(return_value)) + with os.fdopen(args.write_fd, 'w') as write_file_handle: + write_file_handle.write(json.dumps(return_value)) except PermissionError as exception: logger.error(exception.args[0]) sys.exit(EXIT_PERM) @@ -52,14 +62,15 @@ def main(): def _call(module_name, action_name, arguments): """Import the module and run action as superuser""" - if os.getuid() != 0: - raise PermissionError('This action is reserved for root') - if '.' in module_name: raise SyntaxError('Invalid module name') cfg.read() - import_path = module_loader.get_module_import_path(module_name) + if module_name == 'plinth': + import_path = 'plinth' + else: + import_path = module_loader.get_module_import_path(module_name) + try: module = importlib.import_module(import_path + '.privileged') except ModuleNotFoundError as exception: @@ -87,7 +98,8 @@ def _call(module_name, action_name, arguments): 'exception': { 'module': type(exception).__module__, 'name': type(exception).__name__, - 'args': exception.args + 'args': exception.args, + 'traceback': traceback.format_tb(exception.__traceback__) } } diff --git a/actions/backups b/actions/backups deleted file mode 100755 index e83fa8b85..000000000 --- a/actions/backups +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/python3 -# -*- mode: python -*- -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Wrapper to handle backups using borg-backups. -""" - -import argparse -import json -import os -import pathlib -import re -import subprocess -import sys -import tarfile - -from plinth.modules.backups import MANIFESTS_FOLDER -from plinth.utils import Version - -TIMEOUT = 30 -BACKUPS_DATA_PATH = pathlib.Path('/var/lib/plinth/backups-data/') - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - setup = subparsers.add_parser( - 'setup', help='Create repository if it does not already exist') - - init = subparsers.add_parser('init', help='Initialize a repository') - init.add_argument('--encryption', help='Encryption of the repository', - required=True) - - info = subparsers.add_parser('info', help='Show repository information') - - list_repo = subparsers.add_parser('list-repo', - help='List repository contents') - - create_archive = subparsers.add_parser('create-archive', - help='Create archive') - create_archive.add_argument('--paths', help='Paths to include in archive', - nargs='+') - create_archive.add_argument('--comment', - help='Comment text to add to archive', - default='') - - delete_archive = subparsers.add_parser('delete-archive', - help='Delete archive') - - export_help = 'Export archive contents as tar on stdout' - export_tar = subparsers.add_parser('export-tar', help=export_help) - - get_archive_apps = subparsers.add_parser( - 'get-archive-apps', help='Get list of apps included in archive') - - restore_archive = subparsers.add_parser( - 'restore-archive', help='Restore files from an archive') - restore_archive.add_argument('--destination', help='Destination', - required=True) - - for cmd in [ - info, init, list_repo, create_archive, delete_archive, export_tar, - get_archive_apps, restore_archive, setup - ]: - cmd.add_argument('--path', help='Repository or Archive path', - required=False) - cmd.add_argument('--ssh-keyfile', help='Path of private ssh key', - default=None) - - get_exported_archive_apps = subparsers.add_parser( - 'get-exported-archive-apps', - help='Get list of apps included in exported archive file') - get_exported_archive_apps.add_argument('--path', help='Tarball file path', - required=True) - - restore_exported_archive = subparsers.add_parser( - 'restore-exported-archive', - help='Restore files from an exported archive') - restore_exported_archive.add_argument('--path', help='Tarball file path', - required=True) - - dump_settings = subparsers.add_parser('dump-settings', - help='Dump JSON settings to a file') - dump_settings.add_argument('--app-id', - help='ID of the app to dump settings for') - - load_settings = subparsers.add_parser( - 'load-settings', help='Load JSON settings from a file') - load_settings.add_argument('--app-id', - help='ID of the app to load settings for') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_setup(arguments): - """Create repository if it does not already exist.""" - try: - run(['borg', 'info', arguments.path], arguments, check=True) - except subprocess.CalledProcessError: - path = os.path.dirname(arguments.path) - if not os.path.exists(path): - os.makedirs(path) - - init_repository(arguments, encryption='none') - - -def init_repository(arguments, encryption): - """Initialize a local or remote borg repository""" - if encryption != 'none': - if not _read_encryption_passphrase(arguments): - raise ValueError('No encryption passphrase provided') - - cmd = ['borg', 'init', '--encryption', encryption, arguments.path] - run(cmd, arguments) - - -def subcommand_init(arguments): - """Initialize the borg repository.""" - init_repository(arguments, encryption=arguments.encryption) - - -def subcommand_info(arguments): - """Show repository information.""" - run(['borg', 'info', '--json', arguments.path], arguments) - - -def subcommand_list_repo(arguments): - """List repository contents.""" - run(['borg', 'list', '--json', '--format="{comment}"', arguments.path], - arguments) - - -def _get_borg_version(arugments): - """Return the version of borgbackup.""" - process = run(['borg', '--version'], arugments, stdout=subprocess.PIPE) - return process.stdout.decode().split()[1] # Example: "borg 1.1.9" - - -def subcommand_create_archive(arguments): - """Create archive.""" - paths = filter(os.path.exists, arguments.paths) - command = ['borg', 'create', '--json'] - if arguments.comment: - comment = arguments.comment - if Version(_get_borg_version(arguments)) < Version('1.1.10'): - # Undo any placeholder escape sequences in comments as this version - # of borg does not support placeholders. XXX: Drop this code when - # support for borg < 1.1.10 is dropped. - comment = comment.replace('{{', '{').replace('}}', '}') - - command += ['--comment', comment] - - command += [arguments.path] + list(paths) - run(command, arguments) - - -def subcommand_delete_archive(arguments): - """Delete archive.""" - run(['borg', 'delete', arguments.path], arguments) - - -def _extract(archive_path, destination, arguments, locations=None): - """Extract archive contents.""" - prev_dir = os.getcwd() - borg_call = ['borg', 'extract', archive_path] - # do not extract any files when we get an empty locations list - if locations is not None: - borg_call.extend(locations) - - try: - os.chdir(os.path.expanduser(destination)) - # TODO: with python 3.7 use subprocess.run with the 'capture_output' - # argument - process = run(borg_call, arguments, check=False, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if process.returncode != 0: - error = process.stderr.decode() - # Don't fail on the borg error when no files were matched - if "never matched" not in error: - raise subprocess.CalledProcessError(process.returncode, - process.args) - finally: - os.chdir(prev_dir) - - -def subcommand_export_tar(arguments): - """Export archive contents as tar stream on stdout.""" - run(['borg', 'export-tar', arguments.path, '-', '--tar-filter=gzip'], - arguments) - - -def _read_archive_file(archive, filepath, arguments): - """Read the content of a file inside an archive""" - borg_call = ['borg', 'extract', archive, filepath, '--stdout'] - return run(borg_call, arguments, stdout=subprocess.PIPE).stdout.decode() - - -def subcommand_get_archive_apps(arguments): - """Get list of apps included in archive.""" - manifest_folder = os.path.relpath(MANIFESTS_FOLDER, '/') - borg_call = [ - 'borg', 'list', arguments.path, manifest_folder, '--format', - '{path}{NEWLINE}' - ] - try: - borg_process = run(borg_call, arguments, stdout=subprocess.PIPE) - manifest_path = borg_process.stdout.decode().strip() - except subprocess.CalledProcessError: - sys.exit(1) - - manifest = None - if manifest_path: - manifest_data = _read_archive_file(arguments.path, manifest_path, - arguments) - manifest = json.loads(manifest_data) - - if manifest: - for app in _get_apps_of_manifest(manifest): - print(app['name']) - - -def _get_apps_of_manifest(manifest): - """Get apps of a manifest. - - Supports both dict format as well as list format of plinth <=0.42 - - """ - if isinstance(manifest, list): - apps = manifest - elif isinstance(manifest, dict) and 'apps' in manifest: - apps = manifest['apps'] - else: - raise RuntimeError('Unknown manifest format') - - return apps - - -def subcommand_get_exported_archive_apps(arguments): - """Get list of apps included in an exported archive file.""" - manifest = None - with tarfile.open(arguments.path) as tar_handle: - filenames = tar_handle.getnames() - for name in filenames: - if 'var/lib/plinth/backups-manifests/' in name \ - and name.endswith('.json'): - manifest_data = tar_handle.extractfile(name).read() - manifest = json.loads(manifest_data) - break - - if manifest: - for app in _get_apps_of_manifest(manifest): - print(app['name']) - - -def subcommand_restore_archive(arguments): - """Restore files from an archive.""" - _locations = json.loads(arguments.stdin) - locations = _locations['directories'] + _locations['files'] - locations = [os.path.relpath(location, '/') for location in locations] - _extract(arguments.path, arguments.destination, arguments, - locations=locations) - - -def subcommand_restore_exported_archive(arguments): - """Restore files from an exported archive.""" - locations = json.loads(arguments.stdin) - - with tarfile.open(arguments.path) as tar_handle: - for member in tar_handle.getmembers(): - path = '/' + member.name - if path in locations['files']: - tar_handle.extract(member, '/') - else: - for directory in locations['directories']: - if path.startswith(directory): - tar_handle.extract(member, '/') - break - - -def _assert_app_id(app_id): - """Check that app ID is correct.""" - if not re.fullmatch(r'[a-z0-9_]+', app_id): - raise Exception('Invalid App ID') - - -def subcommand_dump_settings(arguments): - """Dump an app's settings to a JSON file.""" - app_id = arguments.app_id - _assert_app_id(app_id) - BACKUPS_DATA_PATH.mkdir(exist_ok=True) - settings_path = BACKUPS_DATA_PATH / f'{app_id}-settings.json' - settings_path.write_text(arguments.stdin) - - -def subcommand_load_settings(arguments): - """Load an app's settings from a JSON file.""" - app_id = arguments.app_id - _assert_app_id(app_id) - settings_path = BACKUPS_DATA_PATH / f'{app_id}-settings.json' - try: - print(settings_path.read_text()) - except FileNotFoundError: - print('{}') - - -def _read_encryption_passphrase(arguments): - """Read encryption passphrase from stdin.""" - if arguments.stdin: - try: - return json.loads(arguments.stdin)['encryption_passphrase'] - except KeyError: - pass - - return None - - -def get_env(arguments): - """Create encryption and ssh kwargs out of given arguments""" - env = dict(os.environ, BORG_RELOCATED_REPO_ACCESS_IS_OK='yes', - LANG='C.UTF-8') - # Always provide BORG_PASSPHRASE (also if empty) so borg does not get stuck - # while asking for a passphrase. - encryption_passphrase = _read_encryption_passphrase(arguments) - env['BORG_PASSPHRASE'] = encryption_passphrase or '' - - return env - - -def run(cmd, arguments, check=True, **kwargs): - """Wrap the command with extra encryption passphrase handling.""" - env = get_env(arguments) - return subprocess.run(cmd, check=check, env=env, **kwargs) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - arguments.stdin = sys.stdin.read() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/bind b/actions/bind deleted file mode 100755 index c92df72f4..000000000 --- a/actions/bind +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for BIND server. -""" - -import argparse -from pathlib import Path - -from plinth import action_utils -from plinth.modules.bind import (CONFIG_FILE, DEFAULT_CONFIG, ZONES_DIR, - set_dnssec, set_forwarders) - - -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - setup = subparsers.add_parser('setup', help='Setup for BIND') - setup.add_argument( - '--old-version', type=int, required=True, - help='Earlier version of the app that is already setup.') - - configure = subparsers.add_parser('configure', help='Configure BIND') - configure.add_argument('--forwarders', - help='List of IP addresses, separated by space') - configure.add_argument('--dnssec', choices=['enable', 'disable'], - help='Enable or disable DNSSEC') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_setup(arguments): - """Setup BIND configuration.""" - if arguments.old_version == 0: - with open(CONFIG_FILE, 'w', encoding='utf-8') as conf_file: - conf_file.write(DEFAULT_CONFIG) - - Path(ZONES_DIR).mkdir(exist_ok=True, parents=True) - - action_utils.service_restart('named') - - -def subcommand_configure(arguments): - """Configure BIND.""" - set_forwarders(arguments.forwarders) - set_dnssec(arguments.dnssec) - action_utils.service_restart('named') - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/calibre b/actions/calibre deleted file mode 100755 index bc8d51cd7..000000000 --- a/actions/calibre +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for calibre. -""" - -import argparse -import json -import pathlib -import shutil -import subprocess - -from plinth.modules import calibre - -LIBRARIES_PATH = pathlib.Path('/var/lib/calibre-server-freedombox/libraries') - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('list-libraries', - help='Return the list of libraries setup') - subparser = subparsers.add_parser('create-library', - help='Create an empty library') - subparser.add_argument('name', help='Name of the new library') - subparser = subparsers.add_parser('delete-library', - help='Delete a library and its contents') - subparser.add_argument('name', help='Name of the library to delete') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_list_libraries(_): - """Return the list of libraries setup.""" - libraries = [] - for library in LIBRARIES_PATH.glob('*/metadata.db'): - libraries.append(str(library.parent.name)) - - print(json.dumps({'libraries': libraries})) - - -def subcommand_create_library(arguments): - """Create an empty library.""" - calibre.validate_library_name(arguments.name) - library = LIBRARIES_PATH / arguments.name - library.mkdir(mode=0o755) # Raise exception if already exists - subprocess.call( - ['calibredb', '--with-library', library, 'list_categories'], - stdout=subprocess.DEVNULL) - - # Force systemd StateDirectory= logic to assign proper ownership to the - # DynamicUser= - shutil.chown(LIBRARIES_PATH.parent, 'root', 'root') - - -def subcommand_delete_library(arguments): - """Delete a library and its contents.""" - calibre.validate_library_name(arguments.name) - library = LIBRARIES_PATH / arguments.name - shutil.rmtree(library) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/config b/actions/config deleted file mode 100755 index 31da406ee..000000000 --- a/actions/config +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/python3 -# -*- mode: python -*- -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for FreedomBox general configuration. -""" - -import argparse -import os - -import augeas - -from plinth import action_utils -from plinth.modules.config import (APACHE_HOMEPAGE_CONF_FILE_NAME, - FREEDOMBOX_APACHE_CONFIG) - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - set_home_page = subparsers.add_parser( - 'set-home-page', - help='Set the home page for this FreedomBox instance.') - set_home_page.add_argument('homepage', - help='path to the webserver home page') - - subparsers.add_parser('reset-home-page', - help='Reset the homepage of the Apache server.') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_set_home_page(arguments): - """Set the default app for this FreedomBox.""" - conf_file_path = os.path.join('/etc/apache2/conf-available', - APACHE_HOMEPAGE_CONF_FILE_NAME) - - redirect_rule = 'RedirectMatch "^/$" "{}"\n'.format(arguments.homepage) - - with open(conf_file_path, 'w', encoding='utf-8') as conf_file: - conf_file.write(redirect_rule) - - action_utils.webserver_enable('freedombox-apache-homepage') - - -def subcommand_reset_home_page(_): - """Sets the Apache web server's home page to the default - /plinth.""" - config_file = FREEDOMBOX_APACHE_CONFIG - default_path = 'plinth' - - 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() - - aug.defvar('conf', '/files' + config_file) - - for match in aug.match('/files' + config_file + - '/directive["RedirectMatch"]'): - if aug.get(match + "/arg[1]") == '''"^/$"''': - aug.set(match + "/arg[2]", '"/{}"'.format(default_path)) - - aug.save() - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/domainname-change b/actions/domainname-change deleted file mode 100755 index ef058297d..000000000 --- a/actions/domainname-change +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: AGPL-3.0-or-later - -domainname="$1" -hostname=$(hostname) - -if [ -z "$domainname" ] ; then - if grep -q 127.0.1.1 /etc/hosts ; then - sed -i "s/127.0.1.1.*/127.0.1.1 $hostname/" /etc/hosts - else - sed -i "/127.0.0.1.*/a \ - 127.0.1.1 $hostname" /etc/hosts - fi -else - if grep -q 127.0.1.1 /etc/hosts ; then - sed -i "s/127.0.1.1.*/127.0.1.1 $hostname.$domainname $hostname/" /etc/hosts - else - sed -i "/127.0.0.1.*/a \ - 127.0.1.1 $hostname.$domainname $hostname" /etc/hosts - fi -fi diff --git a/actions/dynamicdns b/actions/dynamicdns index 3cbe07793..9f035ea7c 100755 --- a/actions/dynamicdns +++ b/actions/dynamicdns @@ -1,159 +1,9 @@ #!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later +"""Legacy configuration helper for Dynamic DNS, kept for compatibility. + +Cron jobs in the earlier implementation used to call into this script with the +sub-commands 'update' and 'success'. This action script now allows for any +arbitrary sub-command to be called and does nothing. It can be removed after +the release of Debian 12 (bookworm). """ -Configuration helper for Dynamic DNS. -""" - -import argparse -import json -import pathlib -import urllib - -_conf_dir = pathlib.Path('/etc/ez-ipupdate/') -_active_config = _conf_dir / 'ez-ipupdate.conf' -_inactive_config = _conf_dir / 'ez-ipupdate.inactive' -_helper_config = _conf_dir / 'ez-ipupdate-plinth.cfg' -_cron_job = pathlib.Path('/etc/cron.d/ez-ipupdate') - - -def parse_arguments(): - """ Return parsed command line arguments as dictionary. """ - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('export-config', - help='Print configuration in JSON format') - subparsers.add_parser('clean', help='Remove all old configuration files') - - subparsers.add_parser('update', help='For backwards compatibility') - subparser = subparsers.add_parser('success', - help='For backwards compatibility') - subparser.add_argument('wan_ip_address') - - subparsers.required = True - return parser.parse_args() - - -def _read_configuration(path, separator='='): - """Read ez-ipupdate configuration.""" - config = {} - for line in path.read_text().splitlines(): - if line.startswith('#'): - continue - - parts = line.partition(separator) - if parts[1]: - config[parts[0].strip()] = parts[2].strip() - else: - config[parts[0].strip()] = True - - return config - - -def subcommand_export_config(_): - """Print the old ez-ipupdate configuration in JSON format.""" - input_config = {} - if _active_config.exists(): - input_config = _read_configuration(_active_config) - elif _inactive_config.exists(): - input_config = _read_configuration(_inactive_config) - - helper = {} - if _helper_config.exists(): - helper.update(_read_configuration(_helper_config, separator=' ')) - - def _clean(value): - value_map = {'enabled': True, 'disabled': False, '': None} - return value_map.get(value, value) - - domain = { - 'service_type': 'gnudip', - 'domain': input_config.get('host'), - 'server': input_config.get('server'), - 'username': input_config.get('user', '').split(':')[0] or None, - 'password': input_config.get('user', '').split(':')[-1] or None, - 'ip_lookup_url': helper.get('IPURL'), - 'update_url': _clean(helper.get('POSTURL')) or None, - 'use_http_basic_auth': _clean(helper.get('POSTAUTH')), - 'disable_ssl_cert_check': _clean(helper.get('POSTSSLIGNORE')), - 'use_ipv6': _clean(helper.get('POSTUSEIPV6')), - } - - if isinstance(domain['update_url'], bool): - # 'POSTURL ' is a line found in the configuration file - domain['update_url'] = None - - if not domain['server']: - domain['service_type'] = 'other' - update_url = domain['update_url'] - try: - server = urllib.parse.urlparse(update_url).netloc - service_types = { - 'dynupdate.noip.com': 'noip.com', - 'dynupdate.no-ip.com': 'noip.com', - 'freedns.afraid.org': 'freedns.afraid.org' - } - domain['service_type'] = service_types.get(server, 'other') - except ValueError: - pass - - # Old logic for 'enabling' the app is as follows: If behind NAT, add - # cronjob. If not behind NAT and type is update URL, add cronjob. If not - # behind NAT and type is GnuDIP, move inactive configuration to active - # configuration and start the ez-ipupdate daemon. - enabled = False - if _cron_job.exists() or (domain['service_type'] == 'gnudip' - and _active_config.exists()): - enabled = True - - output_config = {'enabled': enabled, 'domains': {}} - if domain['domain']: - output_config['domains'][domain['domain']] = domain - - print(json.dumps(output_config)) - - -def subcommand_clean(_): - """Remove all old configuration files.""" - last_update = _conf_dir / 'last-update' - status = _conf_dir / 'ez-ipupdate.status' - current_ip = _conf_dir / 'ez-ipupdate.currentIP' - - cleanup_files = [ - _active_config, _inactive_config, last_update, _helper_config, status, - current_ip - ] - for cleanup_file in cleanup_files: - try: - cleanup_file.rename(cleanup_file.with_suffix('.bak')) - except FileNotFoundError: - pass - - _cron_job.unlink(missing_ok=True) - - -def subcommand_update(_): - """Empty subcommand kept only for backwards compatibility. - - Drop after stable release. - """ - - -def subcommand_success(_): - """Empty subcommand kept only for backwards compatibility. - - Drop after stable release. - """ - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/email b/actions/email deleted file mode 100755 index 28704472b..000000000 --- a/actions/email +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for email server. -""" - -import argparse -import logging -import os -import sys - -import plinth.log -from plinth.modules.email import privileged - -EXIT_SYNTAX = 10 -EXIT_PERM = 20 - -logger = logging.getLogger(__file__) - - -def main(): - """Parse arguments.""" - plinth.log.action_init() - - parser = argparse.ArgumentParser() - parser.add_argument('module', help='Module to trigger action in') - parser.add_argument('action', help='Action to trigger in module') - parser.add_argument('arguments', help='String arguments for action', - nargs='*') - args = parser.parse_args() - - try: - _call(args.module, args.action, args.arguments) - except Exception as exception: - logger.exception(exception) - sys.exit(1) - - -def _call(module_name, action_name, arguments): - """Import the module and run action as superuser.""" - if os.getuid() != 0: - logger.critical('This action is reserved for root') - sys.exit(EXIT_PERM) - - # We only run actions defined in the privileged module - if module_name not in privileged.__all__: - logger.critical('Bad module name: %r', module_name) - sys.exit(EXIT_SYNTAX) - - module = getattr(privileged, module_name) - try: - action = getattr(module, 'action_' + action_name) - except AttributeError: - logger.critical('Bad action: %s/%r', module_name, action_name) - sys.exit(EXIT_SYNTAX) - - for argument in arguments: - if not isinstance(argument, str): - logger.critical('Bad argument: %s', argument) - sys.exit(EXIT_SYNTAX) - - action(*arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/help b/actions/help deleted file mode 100755 index 1c3a58841..000000000 --- a/actions/help +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Actions for help module. -""" - -import argparse -import subprocess - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('get-logs', help='Get latest FreedomBox logs') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_get_logs(_): - """Get latest FreedomBox logs.""" - command = ['journalctl', '--no-pager', '--lines=100', '--unit=plinth'] - subprocess.run(command, check=True) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/hostname-change b/actions/hostname-change deleted file mode 100755 index 3b578d026..000000000 --- a/actions/hostname-change +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: AGPL-3.0-or-later - -hostname="$1" - -if [ -d /run/systemd/system ] ; then - hostnamectl set-hostname --transient --static "$hostname" -else - echo "$hostname" > /etc/hostname - if [ -x /etc/init.d/hostname.sh ] ; then - invoke-rc.d hostname.sh start - else - service hostname start - fi -fi - -service avahi-daemon restart diff --git a/actions/i2p b/actions/i2p deleted file mode 100755 index 0f5e9731b..000000000 --- a/actions/i2p +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Wrapper to list and handle system services -""" - -import argparse -import os - -from plinth import cfg -from plinth.modules.i2p.helpers import RouterEditor, TunnelEditor - -cfg.read() -module_config_path = os.path.join(cfg.config_dir, 'modules-enabled') - -I2P_CONF_DIR = '/var/lib/i2p/i2p-config' - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparser = subparsers.add_parser( - 'add-favorite', help='Add an eepsite to the list of favorites') - subparser.add_argument('--name', help='Name of the entry', required=True) - subparser.add_argument('--url', help='URL of the entry', required=True) - subparser.add_argument('--description', help='Short description', - required=False) - subparser.add_argument('--icon', help='URL to icon', required=False) - - subparser = subparsers.add_parser('set-tunnel-property', - help='Modify configuration of a tunnel') - subparser.add_argument('--name', help='Name of the tunnel', required=True) - subparser.add_argument('--property', help='Property to modify', - required=True) - subparser.add_argument('--value', help='Value to assign', required=True) - - subparsers.required = True - return parser.parse_args() - - -def subcommand_set_tunnel_property(arguments): - """Modify the configuration file for a certain tunnel.""" - editor = TunnelEditor() - editor \ - .read_conf() \ - .set_tunnel_idx(arguments.name) \ - .set_tunnel_prop(arguments.property, arguments.value) \ - .write_conf() - print('Updated "{property}" of {filename} to {value}'.format( - property=editor.calc_prop_path(arguments.property), - filename=editor.conf_filename, value=arguments.value)) - - -def subcommand_add_favorite(arguments): - """ - Adds a favorite to the router.config - - :param arguments: - :type arguments: - """ - url = arguments.url - - editor = RouterEditor() - editor.read_conf().add_favorite(arguments.name, url, arguments.description, - arguments.icon).write_conf() - - print('Added {} to favorites'.format(url)) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/ikiwiki b/actions/ikiwiki deleted file mode 100755 index 4080f9bef..000000000 --- a/actions/ikiwiki +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for ikiwiki -""" - -import argparse -import os -import re -import shutil -import subprocess -import sys - -SETUP_WIKI = '/etc/ikiwiki/plinth-wiki.setup' -SETUP_BLOG = '/etc/ikiwiki/plinth-blog.setup' -SITE_PATH = '/var/www/ikiwiki' -WIKI_PATH = '/var/lib/ikiwiki' - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - # Setup ikiwiki site - subparsers.add_parser('setup', help='Perform first time setup operations') - - # Get wikis and blogs - subparsers.add_parser('get-sites', help='Get wikis and blogs') - - # Create a wiki - create_wiki = subparsers.add_parser('create-wiki', help='Create a wiki') - create_wiki.add_argument('--wiki_name', help='Name of new wiki') - create_wiki.add_argument('--admin_name', help='Administrator account name') - - # Create a blog - create_blog = subparsers.add_parser('create-blog', help='Create a blog') - create_blog.add_argument('--blog_name', help='Name of new blog') - create_blog.add_argument('--admin_name', help='Administrator account name') - - # Delete a wiki or blog - delete = subparsers.add_parser('delete', help='Delete a wiki or blog.') - delete.add_argument('--name', help='Name of wiki or blog to delete.') - - subparsers.required = True - return parser.parse_args() - - -def _is_safe_path(basedir, path): - """Return whether a path is safe.""" - return os.path.realpath(path).startswith(basedir) - - -def subcommand_setup(_): - """Perform first time setup operations.""" - setup() - - -def get_title(site): - """Get blog or wiki title""" - try: - with open(os.path.join(SITE_PATH, site, 'index.html'), - encoding='utf-8') as index_file: - match = re.search(r'(.*)', index_file.read()) - if match: - return match[1] - except FileNotFoundError: - pass - - return site - - -def subcommand_get_sites(_): - """Get wikis and blogs.""" - if os.path.exists(SITE_PATH): - for site in os.listdir(SITE_PATH): - if not os.path.isdir(os.path.join(SITE_PATH, site)): - continue - - title = get_title(site) - print(site, title) - - -def subcommand_create_wiki(arguments): - """Create a wiki.""" - pw_bytes = sys.stdin.read().encode() - proc = subprocess.Popen([ - 'ikiwiki', '-setup', SETUP_WIKI, arguments.wiki_name, - arguments.admin_name - ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, - env=dict(os.environ, PERL_UNICODE='AS')) - outs, errs = proc.communicate(input=pw_bytes + b'\n' + pw_bytes) - print(outs) - print(errs) - - -def subcommand_create_blog(arguments): - """Create a blog.""" - pw_bytes = sys.stdin.read().encode() - proc = subprocess.Popen([ - 'ikiwiki', '-setup', SETUP_BLOG, arguments.blog_name, - arguments.admin_name - ], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, - env=dict(os.environ, PERL_UNICODE='AS')) - outs, errs = proc.communicate(input=pw_bytes + b'\n' + pw_bytes) - print(outs) - print(errs) - - -def subcommand_delete(arguments): - """Delete a wiki or blog.""" - html_folder = os.path.join(SITE_PATH, arguments.name) - wiki_folder = os.path.join(WIKI_PATH, arguments.name) - - if not (_is_safe_path(SITE_PATH, html_folder) - and _is_safe_path(WIKI_PATH, wiki_folder)): - print('Error: {0} is not a correct name.'.format(arguments.name)) - exit(1) - - try: - shutil.rmtree(html_folder) - shutil.rmtree(wiki_folder) - shutil.rmtree(wiki_folder + '.git') - os.remove(wiki_folder + '.setup') - print('Deleted {0}'.format(arguments.name)) - except FileNotFoundError: - print('Error: {0} not found.'.format(arguments.name)) - exit(1) - - -def setup(): - """Write Apache configuration and wiki/blog setup scripts.""" - if not os.path.exists(SITE_PATH): - os.makedirs(SITE_PATH) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/letsencrypt b/actions/letsencrypt index ed9fb04fc..cf0190e04 100755 --- a/actions/letsencrypt +++ b/actions/letsencrypt @@ -1,493 +1,9 @@ #!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later +"""Legacy configuration helper for Let's Encrypt, kept for compatibility. + +LE configuration in the earlier implementation used to call into this script +with the sub-commands 'run-pre-hooks', 'run-renew-hooks' and 'run-post-hooks'. +This action script now allows for any arbitrary sub-command to be called and +does nothing. It can be removed after the release of Debian 12 (bookworm). """ -Configuration helper for Let's Encrypt. -""" - -import argparse -import filecmp -import glob -import importlib -import inspect -import json -import os -import pathlib -import re -import shutil -import subprocess -import sys - -import configobj - -from plinth import action_utils -from plinth import app as app_module -from plinth import cfg -from plinth.modules import letsencrypt as le -from plinth.modules.letsencrypt.components import LetsEncrypt - -TEST_MODE = False -LE_DIRECTORY = '/etc/letsencrypt/' -ETC_SSL_DIRECTORY = '/etc/ssl/' -RENEWAL_DIRECTORY = '/etc/letsencrypt/renewal/' -AUTHENTICATOR = 'webroot' -WEB_ROOT_PATH = '/var/www/html' -APACHE_PREFIX = '/etc/apache2/sites-available/' -APACHE_CONFIGURATION = ''' -Use FreedomBoxTLSSiteMacro {domain} -''' - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - setup_parser = subparsers.add_parser( - 'setup', help='Run any setup/upgrade activities.') - setup_parser.add_argument( - '--old-version', type=int, required=True, - help='Version number being upgraded from or None if setting up first ' - 'time.') - - subparsers.add_parser('get-status', - help='Return the status of configured domains.') - subparser = subparsers.add_parser( - 'get-modified-time', - help='Return the modified time for a certificate.') - subparser.add_argument('--domain', required=True, - help='Domain name to get modified time for') - revoke_parser = subparsers.add_parser( - 'revoke', help='Revoke certificate of a domain and disable website.') - revoke_parser.add_argument('--domain', required=True, - help='Domain name to revoke certificate for') - obtain_parser = subparsers.add_parser( - 'obtain', help='Obtain certificate for a domain and setup website.') - obtain_parser.add_argument('--domain', required=True, - help='Domain name to obtain certificate for') - delete_parser = subparsers.add_parser( - 'delete', help='Delete certificate for a domain and disable website.') - delete_parser.add_argument('--domain', required=True, - help='Domain name to delete certificate of') - - subparser = subparsers.add_parser( - 'copy-certificate', - help='Copy LE certificate to a daemon\'s directory') - subparser.add_argument('--managing-app', required=True, - help='App needing the certificate') - subparser.add_argument('--user-owner', required=True, - help='User who should own the certificate') - subparser.add_argument('--group-owner', required=True, - help='Group that should own the certificate') - subparser.add_argument('--source-private-key-path', required=True, - help='Path to the source private key') - subparser.add_argument( - '--source-certificate-path', required=True, - help='Path to the source certificate with public key') - subparser.add_argument('--private-key-path', required=True, - help='Path to the private key') - subparser.add_argument('--certificate-path', required=True, - help='Path to the certificate with public key') - - subparser = subparsers.add_parser( - 'compare-certificate', - help='Compare LE certificate to one in daemon\'s directory') - subparser.add_argument('--managing-app', required=True, - help='App needing the certificate') - subparser.add_argument('--source-private-key-path', required=True, - help='Path to the source private key') - subparser.add_argument( - '--source-certificate-path', required=True, - help='Path to the source certificate with public key') - subparser.add_argument('--private-key-path', required=True, - help='Path to the private key') - subparser.add_argument('--certificate-path', required=True, - help='Path to the certificate with public key') - - help_hooks = 'Does nothing, kept for compatibility.' - subparser = subparsers.add_parser('run_pre_hooks', help=help_hooks) - subparser.add_argument('--domain') - subparser.add_argument('--modules', nargs='+', default=[]) - - subparser = subparsers.add_parser('run_renew_hooks', help=help_hooks) - subparser.add_argument('--domain') - subparser.add_argument('--modules', nargs='+', default=[]) - - subparser = subparsers.add_parser('run_post_hooks', help=help_hooks) - subparser.add_argument('--domain') - subparser.add_argument('--modules', nargs='+', default=[]) - - subparsers.required = True - return parser.parse_args() - - -def get_certificate_expiry(domain): - """Return the expiry date of a certificate.""" - certificate_file = os.path.join(le.LIVE_DIRECTORY, domain, 'cert.pem') - output = subprocess.check_output( - ['openssl', 'x509', '-enddate', '-noout', '-in', certificate_file]) - return output.decode().strip().split('=')[1] - - -def get_modified_time(domain): - """Return the last modified time of a certificate.""" - certificate_file = pathlib.Path(le.LIVE_DIRECTORY) / domain / 'cert.pem' - return int(certificate_file.stat().st_mtime) - - -def get_validity_status(domain): - """Return validity status of a certificate, e.g. valid, revoked, expired""" - output = subprocess.check_output(['certbot', 'certificates', '-d', domain]) - output = output.decode(sys.stdout.encoding) - - match = re.search(r'INVALID: (.*)\)', output) - if match is not None: - validity = match.group(1).lower() - elif re.search('VALID', output) is not None: - validity = 'valid' - else: - validity = 'unknown' - - return validity - - -def get_status(): - """ - Return Python dictionary of currently configured domains. - Should be run as root, otherwise might yield a wrong, empty answer. - """ - try: - domains = os.listdir(le.LIVE_DIRECTORY) - except OSError: - domains = [] - - domains = [ - domain for domain in domains - if os.path.isdir(os.path.join(le.LIVE_DIRECTORY, domain)) - ] - - domain_status = {} - for domain in domains: - domain_status[domain] = { - 'certificate_available': - True, - 'expiry_date': - get_certificate_expiry(domain), - 'web_enabled': - action_utils.webserver_is_enabled(domain, kind='site'), - 'validity': - get_validity_status(domain), - 'lineage': - str(pathlib.Path(le.LIVE_DIRECTORY) / domain), - 'modified_time': - get_modified_time(domain) - } - return domain_status - - -def subcommand_setup(arguments): - """Upgrade old site configuration to new macro based style. - - Nothing to do for first time setup and for newer versions. - """ - if arguments.old_version == 2: - _remove_old_hooks() - return - - if arguments.old_version != 1: - return - - domain_status = get_status() - with action_utils.WebserverChange() as webserver_change: - for domain in domain_status: - setup_webserver_config(domain, webserver_change) - - -def subcommand_get_status(_): - """Print a JSON dictionary of currently configured domains.""" - domain_status = get_status() - print(json.dumps({'domains': domain_status})) - - -def subcommand_get_modified_time(arguments): - """Print the modified time of a certificate as integer.""" - print(get_modified_time(arguments.domain)) - - -def subcommand_revoke(arguments): - """Disable a domain and revoke the certificate.""" - domain = arguments.domain - - cert_path = pathlib.Path(le.LIVE_DIRECTORY) / domain / 'cert.pem' - if cert_path.exists(): - command = [ - 'certbot', 'revoke', '--non-interactive', '--domain', domain, - '--cert-path', cert_path - ] - if TEST_MODE: - command.append('--staging') - - process = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - _, stderr = process.communicate() - if process.returncode: - print(stderr.decode(), file=sys.stderr) - sys.exit(1) - - action_utils.webserver_disable(domain, kind='site') - - -def subcommand_obtain(arguments): - """Obtain a certificate for a domain and setup website.""" - domain = arguments.domain - - command = [ - 'certbot', 'certonly', '--non-interactive', '--text', '--agree-tos', - '--register-unsafely-without-email', '--domain', arguments.domain, - '--authenticator', AUTHENTICATOR, '--webroot-path', WEB_ROOT_PATH, - '--renew-by-default' - ] - if TEST_MODE: - command.append('--staging') - - process = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - _, stderr = process.communicate() - if process.returncode: - print(stderr.decode(), file=sys.stderr) - sys.exit(1) - - with action_utils.WebserverChange() as webserver_change: - setup_webserver_config(domain, webserver_change) - - -def _remove_old_hooks(): - """Remove old style renewal hooks from individual configuration files. - - This has been replaced with global hooks by adding script files in - directory /etc/letsencrypt/renewal-hooks/{pre,post,deploy}/. - - """ - for file_path in glob.glob(RENEWAL_DIRECTORY + '*.conf'): - try: - _remove_old_hooks_from_file(file_path) - except Exception as exception: - print('Error removing hooks from file:', file_path, exception) - - -def _remove_old_hooks_from_file(file_path): - """Remove old style hooks from a single configuration file.""" - config = configobj.ConfigObj(file_path) - edited = False - for line in config.initial_comment: - if 'edited by plinth' in line.lower(): - edited = True - - if not edited: - return - - config.initial_comment = [ - line for line in config.initial_comment - if 'edited by plinth' not in line.lower() - ] - - if 'pre_hook' in config['renewalparams']: - del config['renewalparams']['pre_hook'] - - if 'renew_hook' in config['renewalparams']: - del config['renewalparams']['renew_hook'] - - if 'post_hook' in config['renewalparams']: - del config['renewalparams']['post_hook'] - - config.write() - - -def subcommand_copy_certificate(arguments): - """Copy certificate from LE directory to daemon's directory. - - Set ownership and permissions as requested needed by the daemon. - - """ - source_private_key_path = pathlib.Path( - arguments.source_private_key_path).resolve() - _assert_source_directory(source_private_key_path) - source_certificate_path = pathlib.Path( - arguments.source_certificate_path).resolve() - _assert_source_directory(source_certificate_path) - - private_key_path = pathlib.Path(arguments.private_key_path).resolve() - _assert_managed_path(arguments.managing_app, private_key_path) - certificate_path = pathlib.Path(arguments.certificate_path).resolve() - _assert_managed_path(arguments.managing_app, certificate_path) - - # Create directories, owned by root - private_key_path.parent.mkdir(mode=0o755, parents=True, exist_ok=True) - certificate_path.parent.mkdir(mode=0o755, parents=True, exist_ok=True) - - # Private key is only accessible to the user owner - old_mask = os.umask(0o177) - shutil.copyfile(source_private_key_path, private_key_path) - - if certificate_path != private_key_path: - # Certificate is only writable by the user owner - os.umask(0o133) - shutil.copyfile(source_certificate_path, certificate_path) - else: - # If private key and certificate are the same file, append one after - # the other. - source_certificate = source_certificate_path.read_bytes() - with private_key_path.open(mode='a+b') as file_handle: - file_handle.write(source_certificate) - - os.umask(old_mask) - - shutil.chown(certificate_path, user=arguments.user_owner, - group=arguments.group_owner) - shutil.chown(private_key_path, user=arguments.user_owner, - group=arguments.group_owner) - - -def subcommand_compare_certificate(arguments): - """Compare LE certificate with an app certificate.""" - source_private_key_path = pathlib.Path(arguments.source_private_key_path) - source_certificate_path = pathlib.Path(arguments.source_certificate_path) - _assert_source_directory(source_private_key_path) - _assert_source_directory(source_certificate_path) - - private_key_path = pathlib.Path(arguments.private_key_path) - certificate_path = pathlib.Path(arguments.certificate_path) - _assert_managed_path(arguments.managing_app, private_key_path) - _assert_managed_path(arguments.managing_app, certificate_path) - - result = False - try: - if filecmp.cmp(source_certificate_path, certificate_path) and \ - filecmp.cmp(source_private_key_path, private_key_path): - result = True - except FileNotFoundError: - result = False - - print(json.dumps({'result': result})) - - -def _assert_source_directory(path): - """Assert that a path is a valid source of a certificates.""" - assert (str(path).startswith(LE_DIRECTORY) - or str(path).startswith(ETC_SSL_DIRECTORY)) - - -def _get_managed_path(path): - """Return the managed path given a certificate path.""" - if '{domain}' in path: - return pathlib.Path(path.partition('{domain}')[0]) - - return pathlib.Path(path).parent - - -def _assert_managed_path(module, path): - """Check that path is in fact managed by module.""" - cfg.read() - module_file = pathlib.Path(cfg.config_dir) / 'modules-enabled' / module - module_path = module_file.read_text().strip() - - module = importlib.import_module(module_path) - module_classes = inspect.getmembers(module, inspect.isclass) - app_classes = [ - cls[1] for cls in module_classes if issubclass(cls[1], app_module.App) - ] - - managed_paths = [] - for cls in app_classes: - app = cls() - components = app.get_components_of_type(LetsEncrypt) - for component in components: - if component.private_key_path: - managed_paths.append( - _get_managed_path(component.private_key_path)) - if component.certificate_path: - managed_paths.append( - _get_managed_path(component.certificate_path)) - - assert set(path.parents).intersection(set(managed_paths)) - - -def subcommand_run_pre_hooks(_): - """Do nothing, kept for legacy LE configuration. - - If new version of Plinth is deployed and before it can update the Let's - Encrypt configuration and remove these old hooks, if a renew operation is - run, then we don't want it to exit with non-zero error code because this - hook could not be run. - - Remove at some point in the future. - - """ - - -def subcommand_run_renew_hooks(_): - """Do nothing, kept for legacy LE configuration. - - If new version of Plinth is deployed and before it can update the Let's - Encrypt configuration and remove these old hooks, if a renew operation is - run, then we don't want it to exit with non-zero error code because this - hook could not be run. - - Remove at some point in the future. - - """ - - -def subcommand_run_post_hooks(_): - """Do nothing, kept for legacy LE configuration. - - If new version of Plinth is deployed and before it can update the Let's - Encrypt configuration and remove these old hooks, if a renew operation is - run, then we don't want it to exit with non-zero error code because this - hook could not be run. - - Remove at some point in the future. - - """ - - -def subcommand_delete(arguments): - """Disable a domain and delete the certificate.""" - domain = arguments.domain - command = ['certbot', 'delete', '--non-interactive', '--cert-name', domain] - process = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - _, stderr = process.communicate() - if process.returncode: - print(stderr.decode(), file=sys.stderr) - sys.exit(1) - - action_utils.webserver_disable(domain, kind='site') - - -def setup_webserver_config(domain, webserver_change): - """Create SSL web server configuration for a domain. - - Do so only if there is no configuration existing. - """ - file_name = os.path.join(APACHE_PREFIX, domain + '.conf') - if os.path.isfile(file_name): - os.rename(file_name, file_name + '.fbx-bak') - - with open(file_name, 'w', encoding='utf-8') as file_handle: - file_handle.write(APACHE_CONFIGURATION.format(domain=domain)) - - webserver_change.enable('freedombox-tls-site-macro', kind='config') - webserver_change.enable(domain, kind='site') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/minetest b/actions/minetest deleted file mode 100755 index f66ef048b..000000000 --- a/actions/minetest +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Minetest server. -""" - -import argparse - -import augeas - -from plinth import action_utils - -CONFIG_FILE = '/etc/minetest/minetest.conf' -AUG_PATH = '/files' + CONFIG_FILE + '/.anon' - - -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - configure = subparsers.add_parser('configure', help='Configure Minetest') - configure.add_argument('--max_players', - help='Set maximum number of players') - configure.add_argument('--creative_mode', choices=['true', 'false'], - help='Set creative mode true/false') - configure.add_argument('--enable_pvp', choices=['true', 'false'], - help='Set player Vs player true/false') - configure.add_argument('--enable_damage', choices=['true', 'false'], - help='Set damage true/false') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_configure(arguments): - """Configure Minetest.""" - aug = load_augeas() - - if arguments.max_players: - set_max_players(aug, arguments.max_players) - if arguments.creative_mode: - set_creative_mode(aug, arguments.creative_mode) - if arguments.enable_pvp: - enable_pvp(aug, arguments.enable_pvp) - if arguments.enable_damage: - enable_damage(aug, arguments.enable_damage) - - action_utils.service_restart('minetest-server') - - -def set_max_players(aug, max_players): - """Sets the number of max players""" - aug.set(AUG_PATH + '/max_users', max_players) - aug.save() - - -def enable_pvp(aug, choice): - """Enables pvp""" - aug.set(AUG_PATH + '/enable_pvp', choice) - aug.save() - - -def set_creative_mode(aug, choice): - """Enables or disables creative mode""" - aug.set(AUG_PATH + '/creative_mode', choice) - aug.save() - - -def enable_damage(aug, choice): - """Enables damage""" - aug.set(AUG_PATH + '/enable_damage', choice) - aug.save() - - -def load_augeas(): - """Initialize Augeas.""" - 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() - return aug - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/networks b/actions/networks deleted file mode 100755 index 7616e598a..000000000 --- a/actions/networks +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -set -e - -# Configure networking for all wired and wireless devices. -# -# Creates network-manager connections. - -function get-interfaces { - WIRED_IFACES=$(nmcli --terse --fields type,device device | grep "^ethernet:" | cut -d: -f2 | sort -V) - NO_OF_WIRED_IFACES=$(echo $WIRED_IFACES | wc -w) - - WIRELESS_IFACES=$(nmcli --terse --fields type,device device | grep "^wifi:" | cut -d: -f2 | sort -V) - NO_OF_WIRELESS_IFACES=$(echo $WIRELESS_IFACES | wc -w) -} - -function add-connection { - local connection_name="$1" - shift - local interface="$1" - shift - local remaining_arguments="$@" - - already_exists=$(nmcli --terse --fields name,device con show | grep "$connection_name:$interface" || true) - if [ -n "$already_exists" ]; then - echo "Connection '$connection_name' already exists for device '$interface', not adding." - else - nmcli con add con-name "$connection_name" ifname "$interface" $remaining_arguments - fi -} - -function activate-connection { - connection_name="$1" - nohup nmcli con up "$connection_name" &>/dev/null & -} - -function configure-regular-interface { - local interface="$1" - local zone="$2" - local connection_name="FreedomBox WAN" - - # Create n-m connection for a regular interface - add-connection "$connection_name" "$interface" type ethernet - nmcli con modify "$connection_name" connection.autoconnect TRUE - nmcli con modify "$connection_name" connection.zone "$zone" - activate-connection "$connection_name" - - echo "Configured interface '$interface' for '$zone' use as '$connection_name'." -} - -function configure-shared-interface { - local interface="$1" - local connection_name="FreedomBox LAN $interface" - - # Create n-m connection for eth1 - add-connection "$connection_name" "$interface" type ethernet - nmcli con modify "$connection_name" connection.autoconnect TRUE - nmcli con modify "$connection_name" connection.zone internal - - # Configure this interface to be shared with other computers. - # - Self-assign an address and network - # - Start and manage DNS server (dnsmasq) - # - Start and manage DHCP server (dnsmasq) - # - Register address with mDNS - # - Add firewall rules for NATing from this interface - nmcli con modify "$connection_name" ipv4.method shared - - activate-connection "$connection_name" - - echo "Configured interface '$interface' for shared use as '$connection_name'." -} - -function configure-wireless-interface { - local interface="$1" - local connection_name="FreedomBox $interface" - local ssid="FreedomBox$interface" - local secret="freedombox123" - - add-connection "$connection_name" "$interface" type wifi ssid "$ssid" - nmcli con modify "$connection_name" connection.autoconnect TRUE - nmcli con modify "$connection_name" connection.zone internal - nmcli con modify "$connection_name" ipv4.method shared - nmcli con modify "$connection_name" wifi.mode ap - nmcli con modify "$connection_name" wifi-sec.key-mgmt wpa-psk - nmcli con modify "$connection_name" wifi-sec.psk "$secret" - activate-connection "$connection_name" - - echo "Configured interface '$interface' for shared use as '$connection_name'." -} - -function multi-wired-setup { - local first_interface="$1" - shift - local remaining_interfaces="$@" - - configure-regular-interface "$first_interface" external - - for interface in $remaining_interfaces - do - configure-shared-interface "$interface" - done -} - -function one-wired-setup { - local interface="$1" - - case $NO_OF_WIRELESS_IFACES in - "0") - configure-regular-interface "$interface" internal - ;; - *) - configure-regular-interface "$interface" external - ;; - esac -} - -function wireless-setup { - local interfaces="$@" - - for interface in $interfaces - do - configure-wireless-interface "$interface" - done -} - -function setup { - echo "Setting up network configuration..." - get-interfaces - - case $NO_OF_WIRED_IFACES in - "0") - echo "No wired interfaces detected." - ;; - "1") - one-wired-setup $WIRED_IFACES - ;; - *) - multi-wired-setup $WIRED_IFACES - esac - - wireless-setup $WIRELESS_IFACES - - echo "Done setting up network configuration." -} - -# -# For a user who installed using freedombox-setup Debian package, when -# FreedomBox Service (Plinth) is run for the first time, don't run network -# setup. This is ensured by checking for the file -# /var/lib/freedombox/is-freedombox-disk-image which will not exist. -# -# For a user who installed using FreedomBox disk image, when FreedomBox Service -# (Plinth) runs for the first time, setup process executes and triggers the -# script due networks module being an essential module. -# -if [ -f "/var/lib/freedombox/is-freedombox-disk-image" ] -then - setup -else - echo "Not a FreedomBox disk image. Skipping network configuration." -fi diff --git a/actions/power b/actions/power deleted file mode 100755 index 4411cf992..000000000 --- a/actions/power +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for power controls. -""" - -import argparse -import subprocess - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('restart', help='Restart the system') - subparsers.add_parser('shutdown', help='Shut down the system') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_restart(_): - """Restart the system.""" - subprocess.call('reboot') - - -def subcommand_shutdown(_): - """Shut down the system.""" - subprocess.call(['shutdown', 'now']) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/quassel b/actions/quassel deleted file mode 100755 index c22e14c5e..000000000 --- a/actions/quassel +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Quassel. -""" - -import argparse -import pathlib - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparser = subparsers.add_parser('set-domain', - help='Setup Quassel configuration') - subparser.add_argument('domain_name', help='Domain name to be allowed') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_set_domain(arguments): - """Write a file containing domain name.""" - domain_file = pathlib.Path('/var/lib/quassel/domain-freedombox') - domain_file.write_text(arguments.domain_name, encoding='utf-8') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/radicale b/actions/radicale deleted file mode 100755 index 4c745e5d8..000000000 --- a/actions/radicale +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Radicale. -""" - -import argparse -import os - -import augeas - -from plinth import action_utils - -CONFIG_FILE = '/etc/radicale/config' -LOG_PATH = '/var/log/radicale' - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - configure = subparsers.add_parser('configure', - help='Configure various options') - configure.add_argument('--rights_type', - help='Set the rights type for radicale') - subparsers.add_parser('fix-paths', help='Ensure paths exists') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_configure(arguments): - """Sets the radicale rights type to a particular value""" - if arguments.rights_type == 'owner_only': - # Default rights file is equivalent to owner_only. - arguments.rights_type = 'from_file' - - aug = load_augeas() - aug.set('/files' + CONFIG_FILE + '/rights/type', arguments.rights_type) - aug.save() - - action_utils.service_try_restart('uwsgi') - - -def subcommand_fix_paths(_): - """Fix log path to work around a bug.""" - # Workaround for bug in radicale's uwsgi script (#931201) - if not os.path.exists(LOG_PATH): - os.makedirs(LOG_PATH) - - -def load_augeas(): - """Initialize Augeas.""" - aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + - augeas.Augeas.NO_MODL_AUTOLOAD) - - # INI file lens - aug.set('/augeas/load/Puppet/lens', 'Puppet.lns') - aug.set('/augeas/load/Puppet/incl[last() + 1]', CONFIG_FILE) - - aug.load() - return aug - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/security b/actions/security deleted file mode 100755 index f61775dcb..000000000 --- a/actions/security +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Helper for security configuration -""" - -import argparse -import os - -from plinth.modules.security import (ACCESS_CONF_FILE, ACCESS_CONF_FILE_OLD, - ACCESS_CONF_SNIPPET, ACCESS_CONF_SNIPPETS) - - -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser( - 'enable-restricted-access', - help='Restrict console login to users in admin or sudo group') - subparsers.add_parser( - 'disable-restricted-access', - help='Don\'t restrict console login to users in admin or sudo group') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_enable_restricted_access(_): - """Restrict console login to users in admin or sudo group.""" - try: - os.mkdir(os.path.dirname(ACCESS_CONF_FILE)) - except FileExistsError: - pass - - with open(ACCESS_CONF_FILE, 'w', encoding='utf-8') as conffile: - conffile.write(ACCESS_CONF_SNIPPET + '\n') - - -def subcommand_disable_restricted_access(_): - """Don't restrict console login to users in admin or sudo group.""" - with open(ACCESS_CONF_FILE_OLD, 'r', encoding='utf-8') as conffile: - lines = conffile.readlines() - - with open(ACCESS_CONF_FILE_OLD, 'w', encoding='utf-8') as conffile: - for line in lines: - if line.strip() not in ACCESS_CONF_SNIPPETS: - conffile.write(line) - - try: - os.remove(ACCESS_CONF_FILE) - except OSError: - pass - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/service b/actions/service deleted file mode 100755 index 2da7c4d3b..000000000 --- a/actions/service +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Wrapper to list and handle system services -""" - -import argparse -import os - -from plinth import action_utils -from plinth import app as app_module -from plinth import cfg, module_loader -from plinth.daemon import Daemon, RelatedDaemon - -cfg.read() -module_config_path = os.path.join(cfg.config_dir, 'modules-enabled') - - -def add_service_action(subparsers, action, help): - parser = subparsers.add_parser(action, help=help) - parser.add_argument('service', help='name of the service') - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - add_service_action(subparsers, 'start', 'start a service') - add_service_action(subparsers, 'stop', 'stop a service') - add_service_action(subparsers, 'enable', 'enable a service') - add_service_action(subparsers, 'disable', 'disable a service') - add_service_action(subparsers, 'restart', 'restart a service') - add_service_action(subparsers, 'try-restart', - 'restart a service if running') - add_service_action(subparsers, 'reload', 'reload a service') - add_service_action(subparsers, 'is-running', 'status of a service') - add_service_action(subparsers, 'is-enabled', 'status a service') - add_service_action(subparsers, 'mask', 'unmask a service') - add_service_action(subparsers, 'unmask', 'unmask a service') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_start(arguments): - action_utils.service_start(arguments.service) - - -def subcommand_stop(arguments): - action_utils.service_stop(arguments.service) - - -def subcommand_enable(arguments): - action_utils.service_enable(arguments.service) - - -def subcommand_disable(arguments): - action_utils.service_disable(arguments.service) - - -def subcommand_restart(arguments): - action_utils.service_restart(arguments.service) - - -def subcommand_try_restart(arguments): - action_utils.service_try_restart(arguments.service) - - -def subcommand_reload(arguments): - action_utils.service_reload(arguments.service) - - -def subcommand_mask(arguments): - action_utils.service_mask(arguments.service) - - -def subcommand_unmask(arguments): - action_utils.service_unmask(arguments.service) - - -def subcommand_is_enabled(arguments): - print(action_utils.service_is_enabled(arguments.service)) - - -def subcommand_is_running(arguments): - print(action_utils.service_is_running(arguments.service)) - - -def _get_managed_services(): - """Get a set of all services managed by FreedomBox.""" - services = set() - module_loader.load_modules() - app_module.apps_init() - for app in app_module.App.list(): - components = app.get_components_of_type(Daemon) - for component in components: - services.add(component.unit) - if component.alias: - services.add(component.alias) - - components = app.get_components_of_type(RelatedDaemon) - for component in components: - services.add(component.unit) - - return services - - -def _assert_service_is_managed_by_plinth(service_name): - managed_services = _get_managed_services() - if service_name not in managed_services: - msg = ("The service '%s' is not managed by FreedomBox. Access is only " - "permitted for services listed in the 'managed_services' " - "variable of any FreedomBox app.") % service_name - raise ValueError(msg) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - if hasattr(arguments, 'service'): - _assert_service_is_managed_by_plinth(arguments.service) - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/sharing b/actions/sharing deleted file mode 100755 index 1cfeb35f1..000000000 --- a/actions/sharing +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for the sharing app. -""" - -import argparse -import json -import os -import pathlib -import re - -import augeas - -from plinth import action_utils - -APACHE_CONFIGURATION = '/etc/apache2/conf-available/sharing-freedombox.conf' - - -def parse_arguments(): - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('list', help='List all existing shares') - - add_parser = subparsers.add_parser('add', help='Add a new share') - add_parser.add_argument('--name', required=True, help='Name of the share') - add_parser.add_argument('--path', required=True, help='Disk path to share') - add_parser.add_argument('--groups', nargs='*', - help='List of groups that can access the share') - add_parser.add_argument('--is-public', required=False, default=False, - action="store_true", - help='Allow public access to this share') - - remove_parser = subparsers.add_parser('remove', - help='Remove an existing share') - remove_parser.add_argument('--name', required=True, - help='Name of the share to remove') - - subparsers.required = True - return parser.parse_args() - - -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.set('/augeas/load/Httpd/lens', 'Httpd.lns') - aug.set('/augeas/load/Httpd/incl[last() + 1]', APACHE_CONFIGURATION) - aug.load() - - aug.defvar('conf', '/files' + APACHE_CONFIGURATION) - - return aug - - -def subcommand_add(arguments): - """Add a share to Apache configuration.""" - name = arguments.name - path = '"' + arguments.path.replace('"', r'\"') + '"' - groups = arguments.groups - is_public = arguments.is_public - url = '/share/' + name - - if not os.path.exists(APACHE_CONFIGURATION): - pathlib.Path(APACHE_CONFIGURATION).touch() - - aug = load_augeas() - shares = _list(aug) - if any([share for share in shares if share['name'] == name]): - raise Exception('Share already present') - - aug.set('$conf/directive[last() + 1]', 'Alias') - aug.set('$conf/directive[last()]/arg[1]', url) - aug.set('$conf/directive[last()]/arg[2]', path) - - aug.set('$conf/Location[last() + 1]/arg', url) - - aug.set('$conf/Location[last()]/directive[last() + 1]', 'Include') - aug.set('$conf/Location[last()]/directive[last()]/arg', - 'includes/freedombox-sharing.conf') - - if not is_public: - aug.set('$conf/Location[last()]/directive[last() + 1]', 'Include') - aug.set('$conf/Location[last()]/directive[last()]/arg', - 'includes/freedombox-single-sign-on.conf') - - aug.set('$conf/Location[last()]/IfModule/arg', 'mod_auth_pubtkt.c') - aug.set('$conf/Location[last()]/IfModule/directive[1]', 'TKTAuthToken') - for group_name in groups: - aug.set( - '$conf/Location[last()]/IfModule/directive[1]/arg[last() + 1]', - group_name) - else: - aug.set('$conf/Location[last()]/directive[last() + 1]', 'Require') - aug.set('$conf/Location[last()]/directive[last()]/arg[1]', 'all') - aug.set('$conf/Location[last()]/directive[last()]/arg[2]', 'granted') - - aug.save() - - with action_utils.WebserverChange() as webserver_change: - webserver_change.enable('sharing-freedombox') - - -def subcommand_remove(arguments): - """Remove a share from Apache configuration.""" - url_to_remove = '/share/' + arguments.name - - aug = load_augeas() - - for directive in aug.match('$conf/directive'): - if aug.get(directive) != 'Alias': - continue - - url = aug.get(directive + '/arg[1]') - if url == url_to_remove: - aug.remove(directive) - - for location in aug.match('$conf/Location'): - url = aug.get(location + '/arg') - if url == url_to_remove: - aug.remove(location) - - aug.save() - - with action_utils.WebserverChange() as webserver_change: - webserver_change.enable('sharing-freedombox') - - -def _get_name_from_url(url): - """Return the name of the share given the URL for it.""" - matches = re.match(r'/share/([a-z0-9\-]*)', url) - if not matches: - raise ValueError - - return matches[1] - - -def _list(aug=None): - """List all Apache configuration shares.""" - if not aug: - aug = load_augeas() - - shares = [] - - for match in aug.match('$conf/directive'): - if aug.get(match) != 'Alias': - continue - - url = aug.get(match + '/arg[1]') - path = aug.get(match + '/arg[2]') - - path = path.removesuffix('"').removeprefix('"') - path = path.replace(r'\"', '"') - try: - name = _get_name_from_url(url) - shares.append({ - 'name': name, - 'path': path, - 'url': '/share/' + name - }) - except ValueError: - continue - - for location in aug.match('$conf/Location'): - url = aug.get(location + '/arg') - - try: - name = _get_name_from_url(url) - except ValueError: - continue - - groups = [] - for group in aug.match(location + '//directive["TKTAuthToken"]/arg'): - groups.append(aug.get(group)) - - def _is_public(): - """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' - - for share in shares: - if share['name'] == name: - share['groups'] = groups - share['is_public'] = _is_public() - - return shares - - -def subcommand_list(_): - """List all Apache configuration shares and print as JSON.""" - print(json.dumps({'shares': _list()})) - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/sshfs b/actions/sshfs deleted file mode 100755 index badfc700b..000000000 --- a/actions/sshfs +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/python3 -# -*- mode: python -*- -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Actions for sshfs. -""" - -import argparse -import json -import os -import subprocess -import sys - -TIMEOUT = 30 - - -class AlreadyMountedError(Exception): - """Exception raised when mount point is already mounted.""" - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - mount = subparsers.add_parser('mount', help='mount an ssh filesystem') - mount.add_argument('--mountpoint', help='Local mountpoint', required=True) - mount.add_argument('--path', help='Remote ssh path to mount', - required=True) - mount.add_argument('--ssh-keyfile', help='Path of private ssh key', - default=None, required=False) - mount.add_argument('--user-known-hosts-file', - help='Path to a custom known_hosts file', - default='/dev/null') - umount = subparsers.add_parser('umount', help='unmount an ssh filesystem') - umount.add_argument('--mountpoint', help='Mountpoint to unmount', - required=True) - is_mounted = subparsers.add_parser( - 'is-mounted', help='Check whether a mountpoint is mounted') - is_mounted.add_argument('--mountpoint', help='Mountpoint to check', - required=True) - - subparsers.required = True - return parser.parse_args() - - -def subcommand_mount(arguments): - """Mount a remote ssh path via sshfs.""" - try: - validate_mountpoint(arguments.mountpoint) - except AlreadyMountedError: - return - - remote_path = arguments.path - kwargs = {} - # the shell would expand ~/ to the local home directory - remote_path = remote_path.replace('~/', '').replace('~', '') - # 'reconnect', 'ServerAliveInternal' and 'ServerAliveCountMax' allow the - # client (FreedomBox) to keep control of the SSH connection even when the - # SSH server misbehaves. Without these options, other commands such as - # '/usr/share/plinth/actions/storage usage-info', 'df', - # '/usr/share/plinth/actions/sshfs is-mounted', or 'mountpoint' might block - # indefinitely (even when manually invoked from the command line). This - # situation has some lateral effects, causing major system instability in - # the course of ~11 days, and leaving the system in such state that the - # only solution is a reboot. - cmd = [ - 'sshfs', remote_path, arguments.mountpoint, '-o', - f'UserKnownHostsFile={arguments.user_known_hosts_file}', '-o', - 'StrictHostKeyChecking=yes', '-o', 'reconnect', '-o', - 'ServerAliveInterval=15', '-o', 'ServerAliveCountMax=3' - ] - if arguments.ssh_keyfile: - cmd += ['-o', 'IdentityFile=' + arguments.ssh_keyfile] - else: - password = read_password() - if not password: - raise ValueError('mount requires either a password or ssh_keyfile') - cmd += ['-o', 'password_stdin'] - kwargs['input'] = password.encode() - - subprocess.run(cmd, check=True, timeout=TIMEOUT, **kwargs) - - -def subcommand_umount(arguments): - """Unmount a mountpoint.""" - subprocess.run(['umount', arguments.mountpoint], check=True) - - -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) - if os.listdir(mountpoint) or not os.path.isdir(mountpoint): - raise ValueError('Mountpoint %s is not an empty directory' % - mountpoint) - else: - os.makedirs(mountpoint) - - -def _is_mounted(mountpoint): - """Return boolean whether a local directory is a mountpoint.""" - cmd = ['mountpoint', '-q', mountpoint] - # mountpoint exits with status non-zero if it didn't find a mountpoint - try: - subprocess.run(cmd, check=True) - return True - except subprocess.CalledProcessError: - return False - - -def subcommand_is_mounted(arguments): - """Print whether a path is already mounted.""" - print(json.dumps(_is_mounted(arguments.mountpoint))) - - -def read_password(): - """Read the password from stdin.""" - if sys.stdin.isatty(): - return '' - - return ''.join(sys.stdin) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/timezone-change b/actions/timezone-change deleted file mode 100755 index 8ba152975..000000000 --- a/actions/timezone-change +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Set time zones with timedatectl (requires root permission). -""" - -import argparse -import subprocess -import sys - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - parser.add_argument( - 'timezone', help='Time zone to set; see "timedatectl list-timezones".') - return parser.parse_args() - - -def _set_timezone(arguments): - """Set time zone with timedatectl.""" - try: - command = ['timedatectl', 'set-timezone', arguments.timezone] - subprocess.run(command, stdout=subprocess.DEVNULL, check=True) - except subprocess.CalledProcessError as exception: - print('Error setting timezone:', exception, file=sys.stderr) - sys.exit(1) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - _set_timezone(arguments) - - -if __name__ == '__main__': - main() diff --git a/conftest.py b/conftest.py index e84b08e08..3ba2576e8 100644 --- a/conftest.py +++ b/conftest.py @@ -148,24 +148,39 @@ def fixture_actions_module(request): return module -@pytest.fixture(name='call_action') -def fixture_call_action(request, capsys, actions_module): - """Run actions with custom root path.""" +@pytest.fixture(name='mock_privileged') +def fixture_mock_privileged(request): + """Mock the privileged decorator to nullify its effects.""" + try: + privileged_modules_to_mock = request.module.privileged_modules_to_mock + except AttributeError: + raise AttributeError( + 'mock_privileged fixture requires "privileged_module_to_mock" ' + 'attribute at module level') - actions_name = getattr(request.module, 'actions_name') + for module_name in privileged_modules_to_mock: + module = importlib.import_module(module_name) + for name, member in module.__dict__.items(): + wrapped = getattr(member, '__wrapped__', None) + if not callable(member) or not wrapped: + continue - def _call_action(*args, **_kwargs): - if isinstance(args[0], list): - argv = [actions_name] + args[0] # Command line style usage - else: - argv = [args[0]] + args[1] # superuser_run style usage + if not getattr(member, '_privileged', False): + continue - with patch('argparse._sys.argv', argv): - actions_module.main() - captured = capsys.readouterr() - return captured.out + setattr(wrapped, '_original_wrapper', member) + module.__dict__[name] = wrapped - return _call_action + yield + + for module_name in privileged_modules_to_mock: + module = importlib.import_module(module_name) + for name, member in module.__dict__.items(): + wrapper = getattr(member, '_original_wrapper', None) + if not callable(member) or not wrapper: + continue + + module.__dict__[name] = wrapper @pytest.fixture(name='splinter_screenshot_dir', scope='session') diff --git a/container b/container index f791f8f97..bf031ca8f 100755 --- a/container +++ b/container @@ -193,7 +193,7 @@ mount -o remount /freedombox if [[ "{distribution}" == "stable" && ! -e $BACKPORTS_SOURCES_LIST ]] then echo "> In container: Enable backports" - /freedombox/actions/upgrades activate-backports + /freedombox/actions/actions upgrades activate_backports --no-args fi echo "> In container: Upgrade packages" @@ -650,8 +650,10 @@ def _setup_users(image_file): str(gid), 'plinth'], stdout=subprocess.DEVNULL) logger.info('In container: Setting up sudo for users "fbx" and "plinth"') - sudo_config = 'plinth ALL=(ALL:ALL) NOPASSWD:SETENV : ' \ - '/usr/share/plinth/actions/* , /freedombox/actions/*\n' \ + sudo_config = 'Cmnd_Alias FREEDOMBOX_ACTION_DEV = /usr/share/plinth/' \ + 'actions/actions, /freedombox/actions/actions\n' \ + 'Defaults!FREEDOMBOX_ACTION_DEV closefrom_override\n' \ + 'plinth ALL=(ALL:ALL) NOPASSWD:SETENV : FREEDOMBOX_ACTION_DEV\n' \ 'fbx ALL=(ALL:ALL) NOPASSWD : ALL\n' _runc(image_file, ['tee', '/etc/sudoers.d/01-freedombox-development'], input=sudo_config.encode(), stdout=subprocess.DEVNULL) @@ -696,7 +698,10 @@ def _setup(image_file, distribution): return logger.info('In container: Disabling automatic updates temporarily') - _runc(image_file, ['/usr/share/plinth/actions/upgrades', 'disable-auto']) + contents = 'APT::Periodic::Update-Package-Lists "0";\n' \ + 'APT::Periodic::Unattended-Upgrade "0";\n' + _runc(image_file, ['tee', '/etc/apt/apt.conf.d/20auto-upgrades'], + input=contents.encode()) logger.info('In container: Disabling FreedomBox service') _runc(image_file, ['systemctl', 'disable', 'plinth'], diff --git a/data/etc/apache2/conf-available/freedombox-tls-site-macro.conf b/data/etc/apache2/conf-available/freedombox-tls-site-macro.conf index 9f8389408..0eecd13ed 100644 --- a/data/etc/apache2/conf-available/freedombox-tls-site-macro.conf +++ b/data/etc/apache2/conf-available/freedombox-tls-site-macro.conf @@ -7,9 +7,6 @@ ServerName $domain DocumentRoot /var/www/html - ErrorLog ${APACHE_LOG_DIR}/error.log - CustomLog ${APACHE_LOG_DIR}/access.log combined - SSLEngine on # Disable TLS1.1 and below. Client support: Firefox: 27, Android: diff --git a/data/etc/apache2/conf-available/freedombox.conf b/data/etc/apache2/conf-available/freedombox.conf index d493cc0de..95023151d 100644 --- a/data/etc/apache2/conf-available/freedombox.conf +++ b/data/etc/apache2/conf-available/freedombox.conf @@ -145,4 +145,7 @@ RedirectMatch "^/$" "/plinth" ## journalctl --identifier apache-error --output cat > error.log ## ErrorLog "|/usr/bin/systemd-cat --identifier=apache-error" +# Remove timestamp at the beginning from the default log format. journald +# records its own timestamp. +ErrorLogFormat "[%-m:%l] [pid %P:tid %{g}T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i" CustomLog "|/usr/bin/systemd-cat --identifier=apache-access" vhost_combined diff --git a/data/etc/sudoers.d/plinth b/data/etc/sudoers.d/plinth index 473da750a..37fbbef1b 100644 --- a/data/etc/sudoers.d/plinth +++ b/data/etc/sudoers.d/plinth @@ -2,7 +2,9 @@ # Allow plinth user to run plinth action scripts with superuser privileges # without needing a password. # -plinth ALL=(ALL:ALL) NOPASSWD:/usr/share/plinth/actions/* +Cmnd_Alias FREEDOMBOX_ACTION = /usr/share/plinth/actions/actions +Defaults!FREEDOMBOX_ACTION closefrom_override +plinth ALL=(ALL:ALL) NOPASSWD:FREEDOMBOX_ACTION # # On FreedomBox, allow all users in the 'admin' LDAP group to execute diff --git a/debian/changelog b/debian/changelog index cd044e50e..2625a8231 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,114 @@ +freedombox (22.22) unstable; urgency=medium + + [ Michael Breidenbach ] + * Translated using Weblate (Swedish) + + [ Tymofii Lytvynenko ] + * Translated using Weblate (Ukrainian) + * Translated using Weblate (Ukrainian) + * Translated using Weblate (Ukrainian) + + [ Jiří Podhorecký ] + * Translated using Weblate (Czech) + + [ Sunil Mohan Adapa ] + * templates: Update HTML meta tags for better description and app-name + * doc: dev: Minor example code refactor + * actions: Allow nested and top-level actions + * actions: Use separate IPC for communicating results + * actions: Implement getting raw output from the process + * actions: Allow actions to be called by other users + * config: Drop ability to set hostname on systems without systemd + * dynamicdns: Check action script with flake8 + * tests: Add fixture to help in testing privileged actions + * apache: Use privileged decorator for actions + * bepasty: Use privileged decorator for actions + * bind: Use privileged decorator for actions + * calibre: Use privileged decorator for actions + * config: Minor update to privileged method signature + * config: Use privileged decorator for actions + * config: Use privileged decorator for set-hostname action + * config: Use privileged decorator for set domainname action + * config: Minor refactor + * coturn: Use privileged decorator for actions + * datetime: Use privileged decorator for actions + * deluge: Use privileged decorator for actions + * dynamicdns: Use privileged decorator for actions + * ejabberd: Use privileged decorator for actions + * email: Use privileged decorator for actions + * firewall: Use privileged decorator, drop showing running status + * gitweb: Use privileged decorator for actions + * help: Use privileged decorator for actions + * i2p: Use privileged decorator for actions + * ikiwiki: Use privileged decorator for actions + * infinoted: Use privileged decorator for actions + * letsencrypt: Use privileged decorator for actions + * matrixsynapse: Use privileged decorator for actions + * mediawiki: Use privileged decorator for actions + * minetest: Use privileged decorator for actions + * minidlna: Use privileged decorator for actions + * minidlna: Use the exposed URL for diagnostic test + * networks: Use privileged decorator for actions + * openvpn: Use privileged decorator for actions + * openvpn: Drop RSA to ECC migration code and two-step setup + * pagekite: Use privileged decorator for actions + * power: Use privileged decorator for actions + * quassel: Use privileged decorator for actions + * radicale: Use privileged decorator for actions + * roundcube: Minor update to comment in privileged actions + * searx: Use privileged decorator for actions + * searx: Show status of public access irrespective of enabled state + * security: Use privileged decorator for actions + * shadowsocks: Use privileged decorator for actions + * sharing: Use privileged decorator for actions + * snapshot: Use privileged decorator for actions + * ssh: Use privileged decorator for actions + * sso: Use privileged decorator for actions + * syncthing: Use privileged decorator for actions + * tor: Use privileged decorator for actions + * transmission: Minor update to privileged method signature + * ttrss: Use privileged decorator for actions + * upgrades: Use privileged decorator for actions + * wireguard: Us privileged decorator for actions + * wordpress: Use privileged decorator for actions + * zoph: Use privileged decorator for actions + * backups: Use privileged decorator for sshfs actions + * samba: Use privileged decorator for actions + * storage: Use privileged decorator for actions + * users: Use privileged decorator for actions + * *: Use privileged decorator for service actions + * backups: Use privileged decorator for backup actions + * *: Use privileged decorator for package actions + * actions: Drop unused superuser_run and related methods + * action_utils: Drop unused progress requests from apt-get + * bind: Drop enabling DNSSEC (deprecated) as it is always enabled + * config: Drop legacy migration of Apache homepage settings + * action_utils: Drop support for non-systemd environments + * apache: Fix logs still going into /var/log files + * wordpress: Update fail2ban filter + * fail2ban: Make fail2ban log to journald + * privacy: Set vendor as FreedomBox for dpkg and popularity-contest + + [ Petter Reinholdtsen ] + * Translated using Weblate (Norwegian Bokmål) + + [ Besnik Bleta ] + * Translated using Weblate (Albanian) + * Translated using Weblate (Albanian) + + [ nbenedek ] + * matrix: Add fail2ban jail + * privacy: Add new system app for popularity-contest + + [ Nikita Epifanov ] + * Translated using Weblate (Russian) + + [ James Valleroy ] + * locale: Update translation strings + * doc: Fetch latest manual + + -- James Valleroy Mon, 10 Oct 2022 21:38:11 -0400 + freedombox (22.21.1~bpo11+1) bullseye-backports; urgency=medium * Rebuild for bullseye-backports. diff --git a/debian/freedombox.maintscript b/debian/freedombox.maintscript index 49e3fb9ac..8f0d298fc 100644 --- a/debian/freedombox.maintscript +++ b/debian/freedombox.maintscript @@ -21,3 +21,5 @@ rm_conffile /etc/plinth/modules-enabled/mldonkey 22.4~ rm_conffile /etc/apache2/conf-available/mldonkey-freedombox.conf 22.4~ rm_conffile /etc/apache2/sites-available/plinth.conf 22.16~ rm_conffile /etc/apache2/sites-available/plinth-ssl.conf 22.16~ +rm_conffile /etc/fail2ban/jail.d/wordpress-auth-freedombox.conf 22.22~ +rm_conffile /etc/fail2ban/filter.d/wordpress-auth-freedombox.conf 22.22~ diff --git a/doc/dev/reference/actions.rst b/doc/dev/reference/actions.rst index 53f21c8cd..4ace1950c 100644 --- a/doc/dev/reference/actions.rst +++ b/doc/dev/reference/actions.rst @@ -13,4 +13,4 @@ else. These actions are also directly usable by a skilled administrator. The following documentation for the ``actions`` module. .. automodule:: plinth.actions - :members: run, superuser_run, run_as_user, _run, privileged + :members: privileged diff --git a/doc/dev/tutorial/customizing.rst b/doc/dev/tutorial/customizing.rst index ff4eaa51d..46c2ad867 100644 --- a/doc/dev/tutorial/customizing.rst +++ b/doc/dev/tutorial/customizing.rst @@ -73,10 +73,9 @@ provide options to the user. Add the following to ``forms.py``. def __init__(self, *args, **kw): validator = DirectoryValidator(username=SYSTEM_USER, check_creatable=True) - super(TransmissionForm, - self).__init__(title=_('Download directory'), - default='/var/lib/transmission-daemon/downloads', - validator=validator, *args, **kw) + super().__init__(title=_('Download directory'), + default='/var/lib/transmission-daemon/downloads', + validator=validator, *args, **kw) This uses a utility provided by the framework and creates a Django form that shows a single option to set the download directory for our Transmission app. diff --git a/doc/manual/en/Hardware.raw.wiki b/doc/manual/en/Hardware.raw.wiki index 1294dd6be..cc969d651 100644 --- a/doc/manual/en/Hardware.raw.wiki +++ b/doc/manual/en/Hardware.raw.wiki @@ -44,8 +44,8 @@ Use these hardware if you are able to download !FreedomBox images and prepare an ||Pine A64+ ||1.2x4||arm64/sunxi ||½,1,2||-||- || - ||1000 || {X} || ||Banana Pro ||1.2x2||armhf/sunxi ||1||-||- || (./) ||1000 || {X} || ||Orange Pi Zero ||?x4 ||armhf/sunxi ||¼,½||-||- || - ||100 || {X} || -||!RockPro64 ||1.4x4+1.8x2||arm64 ||2,4||16,32,64,128|| - || (./) ||1000 || {X} || -||Rock64 ||1.5x4||arm64 ||1,2,4||16,32,64,128|| - || (./) ||1000 || {X} || +||!RockPro64 ||1.4x4+1.8x2||arm64 ||2,4||16,32,64,128|| - || (USB3 or [[https://wiki.pine64.org/wiki/ROCKPro64#SATA_Drives|via PCIe card]]) ||1000 || {X} || +||Rock64 ||1.5x4||arm64 ||1,2,4||16,32,64,128|| - || (USB3) ||1000 || {X} || == Additional Hardware == diff --git a/doc/manual/en/ReleaseNotes.raw.wiki b/doc/manual/en/ReleaseNotes.raw.wiki index 0c8c096ef..9dd3c06c4 100644 --- a/doc/manual/en/ReleaseNotes.raw.wiki +++ b/doc/manual/en/ReleaseNotes.raw.wiki @@ -8,6 +8,43 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f The following are the release notes for each !FreedomBox version. +== FreedomBox 22.22 (2022-10-10) == + +=== Highlights === + + * privacy: Add new system app for popularity-contest + * matrix: Add fail2ban jail + +=== Other Changes === + + * *: Use privileged decorator for actions + * action_utils: Drop support for non-systemd environments + * action_utils: Drop unused progress requests from apt-get + * actions: Allow actions to be called by other users + * actions: Allow nested and top-level actions + * actions: Drop unused superuser_run and related methods + * actions: Implement getting raw output from the process + * actions: Use separate IPC for communicating results + * apache: Fix logs still going into /var/log files + * bind: Drop enabling DNSSEC (deprecated) as it is always enabled + * config: Drop ability to set hostname on systems without systemd + * config: Drop legacy migration of Apache homepage settings + * fail2ban: Make fail2ban log to journald + * firewall: Drop showing running status + * locale: Update translations for Albanian, Czech, Norwegian Bokmål, Russian, Swedish, Ukrainian + * minidlna: Use the exposed URL for diagnostic test + * openvpn: Drop RSA to ECC migration code and two-step setup + * privacy: Set vendor as !FreedomBox for dpkg and popularity-contest + * searx: Show status of public access irrespective of enabled state + * templates: Update HTML meta tags for better description and app-name + * tests: Add fixture to help in testing privileged actions + * wordpress: Update fail2ban filter + +== FreedomBox 22.21.1 (2022-10-01) == + + * locale: Update translations for Bulgarian, Ukrainian + * notification: Don't fail when formatting message strings + == FreedomBox 22.21 (2022-09-26) == * janus: Enable systemd sandboxing diff --git a/doc/manual/en/SecureShell.raw.wiki b/doc/manual/en/SecureShell.raw.wiki index 691426f32..aab11eb43 100644 --- a/doc/manual/en/SecureShell.raw.wiki +++ b/doc/manual/en/SecureShell.raw.wiki @@ -8,7 +8,7 @@ ## BEGIN_INCLUDE -== Secure Shell (SSH) Sever == +== Secure Shell (SSH) Server == === What is Secure Shell? === diff --git a/doc/manual/en/Shaarli.raw.wiki b/doc/manual/en/Shaarli.raw.wiki new file mode 100644 index 000000000..2847cdc2a --- /dev/null +++ b/doc/manual/en/Shaarli.raw.wiki @@ -0,0 +1,34 @@ +#language en + +##TAG:TRANSLATION-HEADER-START +~- [[FreedomBox/Manual/Shaarli|English]] - [[DebianWiki/EditorGuide#translation|(+)]] -~ +##TAG:TRANSLATION-HEADER-END + +<> + +## BEGIN_INCLUDE + +== Shaarli (Bookmarks) == + +|| {{attachment:Shaarli-icon_en_V01.png|Shaarli icon}} || + +'''Available since''': version 21.15 + +=== What is Shaarli? === + +Shaarli is personal (single-user) bookmarking application to install on your !FreedomBox. It can also be used for micro-blogging, pastebin, online notepad and snippet archive. Shaarli is designed as a no-database delicious clone. As such, it provides very fast services, easy backup and import/export links as desktop or mobile browser bookmarks. Links stored can be public or private. Shaarli delivers ATOM and RSS feeds from its minimalist interface. + +{{attachment:Shaarli-screenshot_en_V01.png|Shaarli screenshot|width=800}} + +=== External links === + + * Usage documentation: https://shaarli.readthedocs.io/en/master/Usage/ + +## END_INCLUDE + +Back to [[FreedomBox/Features|Features introduction]] or [[FreedomBox/Manual|manual]] pages. + +<> + +---- +CategoryFreedomBox diff --git a/doc/manual/en/freedombox-manual.raw.wiki b/doc/manual/en/freedombox-manual.raw.wiki index cee8e631d..0c41a34c7 100644 --- a/doc/manual/en/freedombox-manual.raw.wiki +++ b/doc/manual/en/freedombox-manual.raw.wiki @@ -41,6 +41,7 @@ <> <> <> +<> <> <> <> diff --git a/doc/manual/en/images/Shaarli-icon_en_V01.png b/doc/manual/en/images/Shaarli-icon_en_V01.png new file mode 100644 index 000000000..ae9584e2a Binary files /dev/null and b/doc/manual/en/images/Shaarli-icon_en_V01.png differ diff --git a/doc/manual/en/images/Shaarli-screenshot_en_V01.png b/doc/manual/en/images/Shaarli-screenshot_en_V01.png new file mode 100644 index 000000000..b12b44e43 Binary files /dev/null and b/doc/manual/en/images/Shaarli-screenshot_en_V01.png differ diff --git a/doc/manual/es/Manual.raw.wiki b/doc/manual/es/Manual.raw.wiki index cee8e631d..0c41a34c7 100644 --- a/doc/manual/es/Manual.raw.wiki +++ b/doc/manual/es/Manual.raw.wiki @@ -41,6 +41,7 @@ <> <> <> +<> <> <> <> diff --git a/doc/manual/es/ReleaseNotes.raw.wiki b/doc/manual/es/ReleaseNotes.raw.wiki index 0c8c096ef..9dd3c06c4 100644 --- a/doc/manual/es/ReleaseNotes.raw.wiki +++ b/doc/manual/es/ReleaseNotes.raw.wiki @@ -8,6 +8,43 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f The following are the release notes for each !FreedomBox version. +== FreedomBox 22.22 (2022-10-10) == + +=== Highlights === + + * privacy: Add new system app for popularity-contest + * matrix: Add fail2ban jail + +=== Other Changes === + + * *: Use privileged decorator for actions + * action_utils: Drop support for non-systemd environments + * action_utils: Drop unused progress requests from apt-get + * actions: Allow actions to be called by other users + * actions: Allow nested and top-level actions + * actions: Drop unused superuser_run and related methods + * actions: Implement getting raw output from the process + * actions: Use separate IPC for communicating results + * apache: Fix logs still going into /var/log files + * bind: Drop enabling DNSSEC (deprecated) as it is always enabled + * config: Drop ability to set hostname on systems without systemd + * config: Drop legacy migration of Apache homepage settings + * fail2ban: Make fail2ban log to journald + * firewall: Drop showing running status + * locale: Update translations for Albanian, Czech, Norwegian Bokmål, Russian, Swedish, Ukrainian + * minidlna: Use the exposed URL for diagnostic test + * openvpn: Drop RSA to ECC migration code and two-step setup + * privacy: Set vendor as !FreedomBox for dpkg and popularity-contest + * searx: Show status of public access irrespective of enabled state + * templates: Update HTML meta tags for better description and app-name + * tests: Add fixture to help in testing privileged actions + * wordpress: Update fail2ban filter + +== FreedomBox 22.21.1 (2022-10-01) == + + * locale: Update translations for Bulgarian, Ukrainian + * notification: Don't fail when formatting message strings + == FreedomBox 22.21 (2022-09-26) == * janus: Enable systemd sandboxing diff --git a/plinth/__init__.py b/plinth/__init__.py index 856676dbd..00f79f98b 100644 --- a/plinth/__init__.py +++ b/plinth/__init__.py @@ -3,4 +3,4 @@ Package init file. """ -__version__ = '22.21.1' +__version__ = '22.22' diff --git a/plinth/action_utils.py b/plinth/action_utils.py index ffaad50d1..c3d6945f9 100644 --- a/plinth/action_utils.py +++ b/plinth/action_utils.py @@ -39,13 +39,8 @@ def service_is_running(servicename): Does not need to run as root. """ try: - if is_systemd_running(): - subprocess.run(['systemctl', 'status', servicename], check=True, - stdout=subprocess.DEVNULL) - else: - subprocess.run(['service', servicename, 'status'], check=True, - stdout=subprocess.DEVNULL) - + subprocess.run(['systemctl', 'status', servicename], check=True, + stdout=subprocess.DEVNULL) return True except subprocess.CalledProcessError: # If a service is not running we get a status code != 0 and @@ -126,12 +121,8 @@ def service_reload(service_name): def service_action(service_name, action): """Perform the given action on the service_name.""" - if is_systemd_running(): - subprocess.run(['systemctl', action, service_name], - stdout=subprocess.DEVNULL, check=False) - else: - subprocess.run(['service', service_name, action], - stdout=subprocess.DEVNULL, check=False) + subprocess.run(['systemctl', action, service_name], + stdout=subprocess.DEVNULL, check=False) def webserver_is_enabled(name, kind='config'): @@ -405,21 +396,12 @@ def is_disk_image(): def run_apt_command(arguments): """Run apt-get with provided arguments.""" - # Ask apt-get to output its progress to file descriptor 3. - command = [ - 'apt-get', '--assume-yes', '--quiet=2', '--option', 'APT::Status-Fd=3' - ] + arguments + command = ['apt-get', '--assume-yes', '--quiet=2'] + arguments - # Duplicate stdout to file descriptor 3 for this process. - os.dup2(1, 3) - - # Pass on file descriptor 3 instead of closing it. Close stdout - # so that regular output is ignored. env = os.environ.copy() env['DEBIAN_FRONTEND'] = 'noninteractive' process = subprocess.run(command, stdin=subprocess.DEVNULL, - stdout=subprocess.DEVNULL, close_fds=False, - env=env, check=False) + stdout=subprocess.DEVNULL, env=env, check=False) return process.returncode diff --git a/plinth/actions.py b/plinth/actions.py index cb77b4fc7..b98eebab2 100644 --- a/plinth/actions.py +++ b/plinth/actions.py @@ -1,79 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -"""Run specified actions. - -Actions run commands with this contract (version 1.1): - -1. (promise) Super-user actions run as root. Normal actions do not. - -2. (promise) The actions directory can't be changed at run time. - - This guarantees that we can only select from the correct set of actions. - -3. (restriction) Only specifically allowed actions can run. - - A. Scripts in a directory above the actions directory can't be run. - - Arguments (and options) can't coerce the system to run actions in - directories above the actions directory. - - Arguments that fail this validation will raise a ValueError. - - B. Scripts in a directory beneath the actions directory can't be run. - - Arguments (and options) can't coerce the system to run actions in - sub-directories of the actions directory. - - (An important side-effect of this is that the system will not try to - follow symlinks to other action directories.) - - Arguments that fail this validation will raise a ValueError. - - C. Only one action can be called at a time. - - This prevents us from appending multiple (unexpected) actions to - the call. Any special shell characters in the action name will - simply be treated as the action itself when trying to search for - an action. The action will then not be found. - - $ action="echo '$options'; echo 'oops'" - $ options="hi" - $ $action # oops, the file system is gone! - - Arguments that fail this validation will raise a ValueError. - - D. Options can't be used to run other actions: - - $ action="echo '$options'" - $ options="hi'; rm -rf /;'" - $ $action # oops, the file system is gone! - - Any option that tries to include special shell characters will - simply be treated as an option with special characters and will - not be interpreted by the shell. - - Any call wishing to include special shell characters in options - list does not need to escape them. They are taken care of. The - option string is passed to the action exactly as it is passed in. - - E. Actions must exist in the actions directory. - -4. (promise) Options are passed as arguments to the action. - - Options can be provided as a list or as a tuple. - -5. (promise) Output is returned from the command. In case of an - error, ActionError is raised with action, output and error strings - as arguments. - -6. (limitation) Providing the process with input is not possible. - - Don't expect to give the process additional input after it's started. Any - interaction with the spawned process must be carried out through some other - method (maybe the process opens a socket, or something). - -7. Option - -""" +"""Framework to run specified actions with elevated privileges.""" import functools import importlib @@ -81,168 +7,14 @@ import inspect import json import logging import os -import re -import shlex import subprocess -import sys +import threading from plinth import cfg -from plinth.errors import ActionError logger = logging.getLogger(__name__) -def run(action, options=None, input=None, run_in_background=False): - """Safely run a specific action as the current user. - - See actions._run for more information. - """ - return _run(action, options, input, run_in_background, False) - - -def superuser_run(action, options=None, input=None, run_in_background=False, - log_error=True): - """Safely run a specific action as root. - - See actions._run for more information. - """ - return _run(action, options, input, run_in_background, True, - log_error=log_error) - - -def run_as_user(action, options=None, input=None, run_in_background=False, - become_user=None): - """Run a command as a different user. - - If become_user is None, run as current user. - """ - return _run(action, options, input, run_in_background, False, become_user) - - -def _run(action, options=None, input=None, run_in_background=False, - run_as_root=False, become_user=None, log_error=True): - """Safely run a specific action as a normal user or root. - - Actions are pulled from the actions directory. - - - options are added to the action command. - - - input: data (as bytes) that will be sent to the action command's stdin. - - - run_in_background: run asynchronously or wait for the command to - complete. - - - run_as_root: execute the command through sudo. - - """ - if options is None: - options = [] - - # Contract 3A and 3B: don't call anything outside of the actions directory. - if os.sep in action: - raise ValueError('Action cannot contain: ' + os.sep) - - cmd = os.path.join(cfg.actions_dir, action) - if not os.path.realpath(cmd).startswith(cfg.actions_dir): - raise ValueError('Action has to be in directory %s' % cfg.actions_dir) - - # Contract 3C: interpret shell escape sequences as literal file names. - # Contract 3E: fail if the action doesn't exist or exists elsewhere. - if not os.access(cmd, os.F_OK): - raise ValueError('Action must exist in action directory.') - - cmd = [cmd] - - # Contract: 3C, 3D: don't allow shell special characters in - # options be interpreted by the shell. When using - # subprocess.Popen with list invocation and not shell invocation, - # escaping is unnecessary as each argument is passed directly to - # the command and not parsed by a shell. - if options: - if not isinstance(options, (list, tuple)): - raise ValueError('Options must be list or tuple.') - - cmd += list(options) # No escaping necessary - - # Contract 1: commands can run via sudo. - sudo_call = [] - if run_as_root: - sudo_call = ['sudo', '-n'] - elif become_user: - sudo_call = ['sudo', '-n', '-u', become_user] - - if cfg.develop and sudo_call: - # Passing 'env' does not work with sudo, so append the PYTHONPATH - # as part of the command - sudo_call += ['PYTHONPATH=%s' % cfg.file_root] - - if sudo_call: - cmd = sudo_call + cmd - - _log_command(cmd) - - # Contract 3C: don't interpret shell escape sequences. - # Contract 5 (and 6-ish). - kwargs = { - 'stdin': subprocess.PIPE, - 'stdout': subprocess.PIPE, - 'stderr': subprocess.PIPE, - 'shell': False, - } - if cfg.develop: - # In development mode pass on local pythonpath to access Plinth - kwargs['env'] = {'PYTHONPATH': cfg.file_root} - - proc = subprocess.Popen(cmd, **kwargs) - - if not run_in_background: - output, error = proc.communicate(input=input) - output, error = output.decode(), error.decode() - if proc.returncode != 0: - if log_error: - logger.error('Error executing command - %s, %s, %s', cmd, - output, error) - raise ActionError(action, output, error) - - return output - - return proc - - -def _log_command(cmd): - """Log a command with special pretty formatting to catch the eye.""" - cmd = list(cmd) # Make a copy of the command not to affect the original - - prompt = '$' - user = '' - if cmd and cmd[0] == 'sudo': - cmd = cmd[1:] - prompt = '#' - - # Drop -n argument to sudo - if cmd and cmd[0] == '-n': - cmd = cmd[1:] - - # Capture username separately - if len(cmd) > 1 and cmd[0] == '-u': - prompt = '$' - user = cmd[1] - cmd = cmd[2:] - - # Drop environmental variables set via sudo - while cmd and re.match(r'.*=.*', cmd[0]): - cmd = cmd[1:] - - # Strip the command's prefix - if cmd: - cmd[0] = cmd[0].split('/')[-1] - - # Shell escape and join command arguments - cmd = ' '.join([shlex.quote(part) for part in cmd]) - - logger.info('%s%s %s', user, prompt, cmd) - - def privileged(func): """Mark a method as allowed to be run as privileged method. @@ -282,20 +54,118 @@ def privileged(func): def wrapper(*args, **kwargs): module_name = _get_privileged_action_module_name(func) action_name = func.__name__ - json_args = json.dumps({'args': args, 'kwargs': kwargs}) - return_value = superuser_run('actions', [module_name, action_name], - input=json_args.encode()) - return_value = json.loads(return_value) - if return_value['result'] == 'success': - return return_value['return'] - - module = importlib.import_module(return_value['exception']['module']) - exception = getattr(module, return_value['exception']['name']) - raise exception(*return_value['exception']['args']) + return _run_privileged_method_as_process(module_name, action_name, + args, kwargs) return wrapper +def _run_privileged_method_as_process(module_name, action_name, args, kwargs): + """Execute the privileged method in a sub-process with sudo.""" + run_as_user = kwargs.pop('_run_as_user', None) + run_in_background = kwargs.pop('_run_in_background', False) + raw_output = kwargs.pop('_raw_output', False) + log_error = kwargs.pop('_log_error', True) + + read_fd, write_fd = os.pipe() + os.set_inheritable(write_fd, True) + + # Prepare the command + command = ['sudo', '--non-interactive', '--close-from', str(write_fd + 1)] + if run_as_user: + command += ['--user', run_as_user] + + if cfg.develop: + command += [f'PYTHONPATH={cfg.file_root}'] + + command += [ + os.path.join(cfg.actions_dir, 'actions'), module_name, action_name, + '--write-fd', + str(write_fd) + ] + + proc_kwargs = { + 'stdin': subprocess.PIPE, + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + 'shell': False, + 'pass_fds': [write_fd], + } + if cfg.develop: + # In development mode pass on local pythonpath to access Plinth + proc_kwargs['env'] = {'PYTHONPATH': cfg.file_root} + + _log_action(module_name, action_name, run_as_user, run_in_background) + + proc = subprocess.Popen(command, **proc_kwargs) + os.close(write_fd) + + if raw_output: + input_ = json.dumps({'args': args, 'kwargs': kwargs}).encode() + return proc, read_fd, input_ + + buffers = [] + # XXX: Use async to avoid creating a thread. + read_thread = threading.Thread(target=_thread_reader, + args=(read_fd, buffers)) + read_thread.start() + + wait_args = (module_name, action_name, args, kwargs, log_error, proc, + command, read_fd, read_thread, buffers) + if not run_in_background: + return _wait_for_return(*wait_args) + + wait_thread = threading.Thread(target=_wait_for_return, args=wait_args) + wait_thread.start() + + +def _wait_for_return(module_name, action_name, args, kwargs, log_error, proc, + command, read_fd, read_thread, buffers): + """Communicate with the subprocess and wait for its return.""" + json_args = json.dumps({'args': args, 'kwargs': kwargs}) + + output, error = proc.communicate(input=json_args.encode()) + read_thread.join() + if proc.returncode != 0: + logger.error('Error executing command - %s, %s, %s', command, output, + error) + raise subprocess.CalledProcessError(proc.returncode, command) + + try: + return_value = json.loads(b''.join(buffers)) + except json.JSONDecodeError: + logger.error( + 'Error decoding action return value %s..%s(*%s, **%s): %s', + module_name, action_name, args, kwargs, return_value) + raise + + if return_value['result'] == 'success': + return return_value['return'] + + module = importlib.import_module(return_value['exception']['module']) + exception_class = getattr(module, return_value['exception']['name']) + exception = exception_class(*return_value['exception']['args'], output, + error) + if log_error: + logger.error('Error running action %s..%s(*%s, **%s): %s %s %s', + module_name, action_name, args, kwargs, exception, + exception.args, return_value['exception']['traceback']) + + raise exception + + +def _thread_reader(read_fd, buffers): + """Read from the pipe in a separate thread.""" + while True: + buffer = os.read(read_fd, 10240) + if not buffer: + break + + buffers.append(buffer) + + os.close(read_fd) + + def _check_privileged_action_arguments(func): """Check that a privileged action has well defined types.""" argspec = inspect.getfullargspec(func) @@ -311,5 +181,20 @@ def _check_privileged_action_arguments(func): def _get_privileged_action_module_name(func): """Figure out the module name of a privileged action.""" module_name = func.__module__ - module = sys.modules[module_name] - return module.__package__.rpartition('.')[2] + while module_name: + module_name, _, last = module_name.rpartition('.') + if last == 'privileged': + break + + if not module_name: + raise ValueError('Privileged actions must be placed under a ' + 'package/module named privileged') + + return module_name.rpartition('.')[2] + + +def _log_action(module_name, action_name, run_as_user, run_in_background): + """Log an action in a compact format.""" + prompt = f'({run_as_user})$' if run_as_user else '#' + suffix = '&' if run_in_background else '' + logger.info('%s %s..%s(…) %s', prompt, module_name, action_name, suffix) diff --git a/plinth/daemon.py b/plinth/daemon.py index 5d1935e83..de1d8d0a3 100644 --- a/plinth/daemon.py +++ b/plinth/daemon.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Component for managing a background daemon or any systemd unit. -""" +"""Component for managing a background daemon or any systemd unit.""" import socket import subprocess @@ -11,7 +9,7 @@ from django.utils.text import format_lazy from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy -from plinth import action_utils, actions, app +from plinth import action_utils, app class Daemon(app.LeaderComponent): @@ -70,15 +68,17 @@ class Daemon(app.LeaderComponent): def enable(self): """Run operations to enable the daemon/unit.""" - actions.superuser_run('service', ['enable', self.unit]) + from plinth.privileged import service as service_privileged + service_privileged.enable(self.unit) if self.alias: - actions.superuser_run('service', ['enable', self.alias]) + service_privileged.enable(self.alias) def disable(self): """Run operations to disable the daemon/unit.""" - actions.superuser_run('service', ['disable', self.unit]) + from plinth.privileged import service as service_privileged + service_privileged.disable(self.unit) if self.alias: - actions.superuser_run('service', ['disable', self.alias]) + service_privileged.disable(self.alias) def is_running(self): """Return whether the daemon/unit is running.""" diff --git a/plinth/errors.py b/plinth/errors.py index 32d4387f8..4c6bcaeba 100644 --- a/plinth/errors.py +++ b/plinth/errors.py @@ -8,10 +8,6 @@ class PlinthError(Exception): """Base class for all FreedomBox specific errors.""" -class ActionError(PlinthError): - """Use this error for exceptions when executing an action.""" - - class PackageNotInstalledError(PlinthError): """Could not complete module setup due to missing package.""" diff --git a/plinth/frontpage.py b/plinth/frontpage.py index 0fd7e8864..012ba3c75 100644 --- a/plinth/frontpage.py +++ b/plinth/frontpage.py @@ -1,15 +1,12 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Manage application shortcuts on front page. -""" +"""Manage application shortcuts on front page.""" import json import logging import pathlib from plinth import app, cfg - -from . import actions +from plinth.modules.users import privileged as users_privileged logger = logging.getLogger(__name__) @@ -116,8 +113,7 @@ class Shortcut(app.FollowerComponent): return cls._all_shortcuts # XXX: Turn this into an API call in users module and cache - output = actions.superuser_run('users', ['get-user-groups', username]) - user_groups = set(output.strip().split('\n')) + user_groups = set(users_privileged.get_user_groups(username)) if 'admin' in user_groups: # Admin has access to all services return cls._all_shortcuts diff --git a/plinth/locale/ar/LC_MESSAGES/django.po b/plinth/locale/ar/LC_MESSAGES/django.po index 6300d4ab1..0752eade6 100644 --- a/plinth/locale/ar/LC_MESSAGES/django.po +++ b/plinth/locale/ar/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-03-31 09:12+0000\n" "Last-Translator: abidin toumi \n" "Language-Team: Arabic calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1022,20 +1015,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1073,24 +1066,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1186,47 +1179,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1234,7 +1227,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1464,11 +1457,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1580,7 +1573,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1635,13 +1628,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1763,14 +1756,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1778,7 +1771,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1788,13 +1781,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1919,7 +1912,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1927,7 +1920,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1947,61 +1940,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2047,7 +2031,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2058,73 +2042,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2168,19 +2152,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2473,7 +2457,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2481,31 +2465,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2542,14 +2526,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2558,15 +2542,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2620,41 +2604,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2662,11 +2646,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2712,7 +2696,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2730,7 +2714,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2740,7 +2724,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2748,15 +2732,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2819,41 +2803,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2863,14 +2847,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2951,7 +2935,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2959,7 +2943,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2968,18 +2952,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3048,35 +3032,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3085,11 +3069,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3134,7 +3118,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3293,19 +3277,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3651,7 +3635,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3756,7 +3740,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3772,7 +3756,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3785,7 +3769,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4321,7 +4305,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4332,20 +4316,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4355,61 +4339,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4418,33 +4370,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4453,87 +4405,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4567,29 +4519,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4631,8 +4583,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4674,6 +4626,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4705,7 +4688,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4716,7 +4699,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4736,7 +4719,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4746,19 +4729,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4817,7 +4800,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4884,7 +4867,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4897,13 +4880,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4912,31 +4895,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5014,15 +4997,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5048,51 +5031,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5245,14 +5228,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5261,97 +5244,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5388,26 +5371,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5415,14 +5398,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5516,7 +5499,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5564,57 +5547,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5622,7 +5605,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5655,14 +5638,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5675,7 +5650,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5683,143 +5658,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5853,7 +5828,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5871,30 +5846,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5902,7 +5877,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5914,20 +5889,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5936,47 +5911,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6074,11 +6049,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6131,31 +6106,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6163,12 +6138,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6176,33 +6151,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6350,51 +6325,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6402,15 +6377,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6428,21 +6403,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6451,12 +6426,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6472,41 +6447,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6523,12 +6498,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6566,17 +6541,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6607,34 +6582,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6943,7 +6918,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6952,7 +6927,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6961,26 +6936,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6994,7 +6969,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7007,7 +6982,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7015,11 +6990,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7068,108 +7043,104 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "حدث خطأ أثناء تثبيت التطبيق: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "حدث خطأ أثناء تثبيت التطبيق: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "خطأ أثناء تثبيت التطبيق: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "خطأ أثناء تثبيت التطبيق: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "ثُبت التطبيق." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "خطأ أثناء تثبيت التطبيق: {error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "حدث خطأ أثناء تثبيت التطبيق: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "خطأ أثناء تثبيت التطبيق: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "ثُبت التطبيق." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7220,53 +7191,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/ar_SA/LC_MESSAGES/django.po b/plinth/locale/ar_SA/LC_MESSAGES/django.po index fb17132ed..1316ce4f9 100644 --- a/plinth/locale/ar_SA/LC_MESSAGES/django.po +++ b/plinth/locale/ar_SA/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2020-06-10 15:41+0000\n" "Last-Translator: aiman an \n" "Language-Team: Arabic (Saudi Arabia) calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1022,20 +1015,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1073,24 +1066,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1186,47 +1179,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1234,7 +1227,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1464,11 +1457,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1580,7 +1573,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1635,13 +1628,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1763,14 +1756,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1778,7 +1771,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1788,13 +1781,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1921,7 +1914,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1929,7 +1922,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1949,61 +1942,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2049,7 +2033,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2060,73 +2044,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2170,19 +2154,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2475,7 +2459,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2483,31 +2467,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2544,14 +2528,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2560,15 +2544,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2622,41 +2606,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2664,11 +2648,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2714,7 +2698,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2732,7 +2716,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2742,7 +2726,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2750,15 +2734,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2821,41 +2805,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2865,14 +2849,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2953,7 +2937,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2961,7 +2945,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2970,18 +2954,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3052,35 +3036,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3089,11 +3073,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3138,7 +3122,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3297,19 +3281,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3655,7 +3639,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3760,7 +3744,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3776,7 +3760,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3789,7 +3773,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4325,7 +4309,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4336,20 +4320,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4359,61 +4343,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4422,33 +4374,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4457,87 +4409,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4571,29 +4523,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4635,8 +4587,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4678,6 +4630,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4709,7 +4692,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4720,7 +4703,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4740,7 +4723,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4750,19 +4733,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4821,7 +4804,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4888,7 +4871,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4901,13 +4884,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4916,31 +4899,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5018,15 +5001,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5052,51 +5035,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5249,14 +5232,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5265,97 +5248,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5392,26 +5375,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5419,14 +5402,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5520,7 +5503,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5568,57 +5551,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5626,7 +5609,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5659,14 +5642,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5679,7 +5654,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5687,143 +5662,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5857,7 +5832,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5875,30 +5850,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5906,7 +5881,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5918,20 +5893,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5940,47 +5915,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6078,11 +6053,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6135,31 +6110,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6167,12 +6142,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6180,33 +6155,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6354,51 +6329,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6406,15 +6381,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6432,21 +6407,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6455,12 +6430,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6476,41 +6451,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6527,12 +6502,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6570,17 +6545,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6611,34 +6586,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6947,7 +6922,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6956,7 +6931,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6965,26 +6940,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6998,7 +6973,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7011,7 +6986,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7019,11 +6994,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7072,108 +7047,104 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "خطأ في تثبيت التطبيق :{string}{details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "خطأ في تثبيت التطبيق :{string}{details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "خطأ في تثبيت التطبيق:{error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "خطأ في تثبيت التطبيق:{error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "تم تثبيت التطبيق." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "خطأ في تثبيت التطبيق:{error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "خطأ في تثبيت التطبيق :{string}{details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "خطأ في تثبيت التطبيق:{error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "تم تثبيت التطبيق." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7224,53 +7195,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/bg/LC_MESSAGES/django.po b/plinth/locale/bg/LC_MESSAGES/django.po index 1aede025c..c5243a633 100644 --- a/plinth/locale/bg/LC_MESSAGES/django.po +++ b/plinth/locale/bg/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-10-01 13:58+0000\n" "Last-Translator: 109247019824 \n" "Language-Team: Bulgarian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1042,7 +1035,7 @@ msgstr "" "Само букви от английската азбука, цифри, символите _ . и - без интервали и " "специални символи. Пример: My_Library_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1088,20 +1081,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1141,7 +1134,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1149,18 +1142,18 @@ msgstr "" "Тук можете да направите някои общи настройки, като име на хост, име на " "домейн, начална страница на сървъра и др." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Общи настройки" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Настройки" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1274,47 +1267,47 @@ msgstr "" "Дневникът съдържа информация, за това кой е достъпвал системата, както и " "информация от различни услуги за отстраняване на дефекти" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Грешка при задаване на името на хоста: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Името на хоста е зададено" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Грешка при задаване на името на домейна: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Името на домейна е зададено" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Грешка при задаване на началната страница на сървъра: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Началната страница на сървъра е зададена" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Грешка при промяна на разширения режим: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Разширените приложения и възможности се показват" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Разширените приложения и възможности са скрити" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1322,7 +1315,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1564,11 +1557,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1680,7 +1673,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1735,13 +1728,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client потребител с вход в " "{box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1868,14 +1861,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1883,7 +1876,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1893,13 +1886,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2026,7 +2019,7 @@ msgstr "Порт" msgid "Host/Target/Value" msgstr "Хост/цел/стойност" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2037,7 +2030,7 @@ msgstr "" "мрежов трафик в и от {box_name}. Поддържането на включена и правилно " "настроена защитна стена намалява риска от заплахи за сигурността от интернет." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Защитна стена" @@ -2057,53 +2050,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Порт {name} ({details}) недостъпен за външните мрежи" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Демонът на защитната стена не работи. Стартирайте го. Защитната стена на " -"%(box_name)s по подразбиране е включена. Всички системи на базата на Дебиан, " -"каквато е %(box_name)s, можете да я стартирате с командата „service " -"firewalld start“, а при устройства със systemd командата е „systemctl start " -"firewalld“." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Услуга/порт" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Включено" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Изключено" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Разрешено" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Разрешено (само вътрешни)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Разрешено (само външни)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Блокирано" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2113,13 +2092,13 @@ msgstr "" "бива разрешена и в защитната стена, а когато я спрете, тя бива забранена и в " "защитната стена." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Разширени" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2173,7 +2152,7 @@ msgstr "Начало на настройката" msgid "Setup Complete" msgstr "Настройката е завършена" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2184,73 +2163,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Обикновен хостинг на Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2294,19 +2273,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Хранилището е променено." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Промяна на хранилище" @@ -2606,7 +2585,7 @@ msgstr "Относно {box_name}" msgid "{box_name} Manual" msgstr "Руководство за {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2614,31 +2593,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2675,14 +2654,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2691,15 +2670,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2753,41 +2732,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2795,11 +2774,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2845,7 +2824,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2863,7 +2842,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2873,7 +2852,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2881,15 +2860,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Сертификати" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Не може да бъде извършена проба: Не са настроени домейни." @@ -2952,41 +2931,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2996,14 +2975,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3084,7 +3063,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3092,7 +3071,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3101,18 +3080,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3184,35 +3163,35 @@ msgstr "Паролата е променена" msgid "Password update failed. Please choose a stronger password" msgstr "Паролата не е променена. Изберете по-сложна парола" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Името на домейна е променено" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Името на страницата е променено" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3225,11 +3204,11 @@ msgstr "" "по подразбиране (30000). За да се свържете със сървъра, е необходим клиент за Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Пясъчник с блокове" @@ -3279,7 +3258,7 @@ msgstr "" msgid "Address" msgstr "Адрес" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3438,19 +3417,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3796,7 +3775,7 @@ msgstr "Редактиране на връзката" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Редактиране" @@ -3901,7 +3880,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3917,7 +3896,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3930,7 +3909,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Сигурност" @@ -4466,7 +4445,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4477,20 +4456,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4500,61 +4479,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4563,33 +4510,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4598,87 +4545,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4712,29 +4659,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4776,8 +4723,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Рестарт" @@ -4825,6 +4772,37 @@ msgstr "" msgid "Shut Down Now" msgstr "Изключване" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4856,7 +4834,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4867,7 +4845,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4887,7 +4865,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4897,19 +4875,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Календар и адресна книга" @@ -4968,7 +4946,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Правата за достъп са променени" @@ -5045,7 +5023,7 @@ msgstr "" "RSS, за да следвате различни страници. При добавяне на емисия, включете " "удостоверяването и използвайте данните за вход на {box_name}." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Четене и абонамент за новинарски емисии" @@ -5058,13 +5036,13 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "Създател на емисии на RSS" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5073,31 +5051,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5175,15 +5153,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "Диск с OS на FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5209,51 +5187,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "Грешка при забраняване на споделянето: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5431,14 +5409,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5447,97 +5425,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5574,26 +5552,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5601,14 +5579,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5702,7 +5680,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5750,57 +5728,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Настройките на моментните снимки на хранилището са променени" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5808,7 +5786,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5841,14 +5819,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5861,7 +5831,7 @@ msgstr "Вход" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5869,143 +5839,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6039,7 +6009,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6057,30 +6027,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6088,7 +6058,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6100,20 +6070,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6122,7 +6092,7 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6131,40 +6101,40 @@ msgstr "" "На {box_name} е достъпен порт на Tor SOCKS за вътрешни мрежи на порт 9050 от " "TCP." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6270,11 +6240,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Настройките са променени" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Грешка при настройка на приложението: {error}" @@ -6334,14 +6304,14 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -6350,17 +6320,17 @@ msgstr "" "Ако е отметнато, достъп до Tiny Tiny RSS ще има всеки потребител, принадлежащ към групата feed-reader." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Четец на абонаменти за новини" @@ -6368,14 +6338,14 @@ msgstr "Четец на абонаменти за новини" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Проверява и прилага последните издания на софтуера и обновявания на " "сигурността." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6383,33 +6353,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Обновяване на софтуера" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox е обновен" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Обновяването на дистрибуцията не може да бъде стартирано" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6585,44 +6555,44 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Надграждане на дистрибуцията до тестова" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Честото обновяване на възможности е включено." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Начало на опит за обновяване на дистрибуцията." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -6633,7 +6603,7 @@ msgstr "" "получи достъп, някои приложения още имат изискване потребителският профил да " "бъде част от определена група." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6645,15 +6615,15 @@ msgstr "" "администратори могат да променят приложенията и настройките на " "системата." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Потребители и групи" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Достъп до всички услуги и системни настройки" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Проверете записа на LDAP „{search_item}“" @@ -6672,11 +6642,11 @@ msgid "" msgstr "" "Задължително. 150 знака или по-малко. Само латински букви, цифри и @/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Парола за удостоверяване" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -6684,11 +6654,11 @@ msgstr "" "За да разрешите промяната на профила, въведете паролата на потребителя " "„{user}“." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Грешна парола." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6697,12 +6667,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Не е създаден потребител в LDAP: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Новият потребител не е добавен към групата {group}: {error}" @@ -6722,41 +6692,41 @@ msgstr "" "няколко ключа, по един на ред. Празните редове и редовете, започващи с #, ще " "бъдат пренебрегнати." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Потребителят на LDAP не е преименуван." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Потребителят не е премахнат от групата." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Потребителят не е добавен към групата." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Ключовете на SSH не са зададени." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Състоянието на потребителя не е променено." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Паролата на потребителя на LDAP не е променена." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Новият потребител не е добавен към администраторската група: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Достъпът до конзолата не е ограничен: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Профилът е създаден и вече сте влезли" @@ -6773,12 +6743,12 @@ msgstr "Запазване на парола" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Създаване на потребител" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Премахване на потребител" @@ -6820,13 +6790,19 @@ msgid "The following administrator accounts exist in the system." msgstr "В системата съществуват следните администраторски профили." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "а да създадете профил, който може да се използва с %(box_name)s, премахнете " "тези профили от командния ред и презаредете страницата. Чрез командния ред " @@ -6835,7 +6811,7 @@ msgstr "" "прескочете тази стъпка." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Поребители" @@ -6868,34 +6844,34 @@ msgstr "" msgid "Save Changes" msgstr "Запазване на промените" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Потребителят %(username)s е създаден." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Потребителят %(username)s е променен." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Промяна на потребител" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Потребителят {user} е премахнат." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Потребителят на LDAP не е премахнат." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Промяна на парола" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Паролата е променена." @@ -7204,7 +7180,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7213,7 +7189,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7222,26 +7198,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7255,7 +7231,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7268,7 +7244,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7276,11 +7252,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7331,96 +7307,92 @@ msgstr "Изчакване да започне: {name}" msgid "Finished: {name}" msgstr "Готово: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Пакетът „{expression}“ е недостъпен за инсталиране" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "Грешка при изпълняване на apt-get" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Времето за изчакване на диспечера на пакети е изтекло" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Инсталиране на приложение" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Обновяване на приложение" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Грешка при инсталиране на приложението: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Грешка при обновяване на приложението: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Грешка при инсталиране на приложението: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Грешка при обновяване на приложението: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "Приложението е инсталирано." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "Приложението е обновено" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Премахване на приложение" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Грешка при премахване на приложението: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Грешка при премахване на приложението: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "Приложението е премахнато." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Обновяване на пакетите на приложението" @@ -7471,53 +7443,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "Услугата %(service_name)s не работи." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Начало" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Начало" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Приложения" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Приложения" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Системни" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Системни" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Смяна на парола" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Изключване" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Изход" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Избор на език" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Вход" @@ -7784,6 +7757,22 @@ msgstr "преди премахване на {app_id}" msgid "Gujarati" msgstr "Гуджарати" +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Демонът на защитната стена не работи. Стартирайте го. Защитната стена на " +#~ "%(box_name)s по подразбиране е включена. Всички системи на базата на " +#~ "Дебиан, каквато е %(box_name)s, можете да я стартирате с командата " +#~ "„service firewalld start“, а при устройства със systemd командата е " +#~ "„systemctl start firewalld“." + +#~ msgid "Error running apt-get" +#~ msgstr "Грешка при изпълняване на apt-get" + #~ msgid "Tor configuration is being updated" #~ msgstr "В момента настройките на Тор се обновяват" diff --git a/plinth/locale/bn/LC_MESSAGES/django.po b/plinth/locale/bn/LC_MESSAGES/django.po index ac1466ac6..2e8b51b6b 100644 --- a/plinth/locale/bn/LC_MESSAGES/django.po +++ b/plinth/locale/bn/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-06-16 07:33+0000\n" "Last-Translator: Oymate \n" "Language-Team: Bengali calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1021,20 +1014,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1072,24 +1065,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "কনফিগার" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1185,47 +1178,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1233,7 +1226,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1464,11 +1457,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1580,7 +1573,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1635,13 +1628,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ইজ্যাবার্ড" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1765,14 +1758,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1780,7 +1773,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1790,13 +1783,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1933,7 +1926,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1941,7 +1934,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "ফায়ারওয়্যাল" @@ -1961,61 +1954,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "সেবা/পোর্ট" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "সক্রিয়" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "নিষ্ক্রিয়" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "অনুমোদিত" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "অবরুদ্ধ" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2061,7 +2045,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2072,73 +2056,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2182,19 +2166,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2487,7 +2471,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2495,31 +2479,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2556,14 +2540,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2572,15 +2556,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ইকিউইকি" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2634,41 +2618,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2676,11 +2660,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "ইফিনোটেড" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2726,7 +2710,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2744,7 +2728,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2754,7 +2738,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2762,15 +2746,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "অনুমতিপত্র" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2833,41 +2817,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2877,14 +2861,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2965,7 +2949,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2973,7 +2957,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2982,18 +2966,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3064,35 +3048,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3101,11 +3085,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "মাইনটেস্ট" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3150,7 +3134,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3309,19 +3293,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3667,7 +3651,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3772,7 +3756,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3788,7 +3772,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3801,7 +3785,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4337,7 +4321,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4348,20 +4332,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4371,61 +4355,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4434,33 +4386,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4469,87 +4421,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4583,29 +4535,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4647,8 +4599,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4690,6 +4642,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4721,7 +4704,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4732,7 +4715,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4752,7 +4735,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4762,19 +4745,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4833,7 +4816,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4900,7 +4883,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4913,13 +4896,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4928,31 +4911,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5030,17 +5013,17 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "ফ্রিডমবক্স" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5066,51 +5049,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5263,14 +5246,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5279,97 +5262,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5406,26 +5389,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5433,14 +5416,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5534,7 +5517,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5582,57 +5565,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5640,7 +5623,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5673,14 +5656,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5693,7 +5668,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5701,143 +5676,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5871,7 +5846,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5889,30 +5864,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5920,7 +5895,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5932,20 +5907,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5954,47 +5929,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6092,13 +6067,13 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "Configuration" msgid "Updating configuration" msgstr "পছন্দসমূহ" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6150,31 +6125,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6182,12 +6157,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6195,33 +6170,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6369,51 +6344,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6421,15 +6396,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6447,21 +6422,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6470,12 +6445,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6491,41 +6466,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6542,12 +6517,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6585,17 +6560,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6626,34 +6601,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6962,7 +6937,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6971,7 +6946,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6980,26 +6955,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7013,7 +6988,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7026,7 +7001,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7034,11 +7009,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7087,96 +7062,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7227,53 +7198,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/cs/LC_MESSAGES/django.po b/plinth/locale/cs/LC_MESSAGES/django.po index 0f4dc5804..8fdffcf32 100644 --- a/plinth/locale/cs/LC_MESSAGES/django.po +++ b/plinth/locale/cs/LC_MESSAGES/django.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" -"PO-Revision-Date: 2022-09-14 17:19+0000\n" -"Last-Translator: ikmaak \n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" +"PO-Revision-Date: 2022-10-05 09:23+0000\n" +"Last-Translator: Jiří Podhorecký \n" "Language-Team: Czech \n" "Language: cs\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: doc/dev/_templates/layout.html:11 msgid "Page source" @@ -115,17 +115,17 @@ msgstr "Webový server" msgid "{box_name} Web Interface (Plinth)" msgstr "Webové rozhraní {box_name} (Plinth)" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "Přístup na URL adrese {url} na tcp{kind}" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "Přístup na URL adrese {url}" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -141,24 +141,24 @@ msgstr "" "nutné a funguje pouze na vnitřních sítích. Je možné ho vypnout a posílit tak " "zabezpečení, hlavně v případě připojení na hostilní místní síť." -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "Zjišťování služby" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "Doména místní sítě" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "Zálohy umožňují vytváření a správu zálohových archivů." -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "Zálohy" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." @@ -166,18 +166,18 @@ msgstr "" "Povolit automatický plán zálohování pro bezpečnost dat. Upřednostněte " "šifrované vzdálené umístění zálohování nebo další připojený disk." -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "Povolení plánu zálohování" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "Jít na {app_name}" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " @@ -186,7 +186,7 @@ msgstr "" "Naplánované zálohování se nezdařilo. Minulé pokusy o zálohování s počtem " "chyb {error_count} nebyly úspěšné. Poslední chyba je: {error_message}" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "Chyba při zálohování" @@ -331,7 +331,7 @@ msgstr "" msgid "Key in Repository" msgstr "Klíč v úložišti" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "Žádný" @@ -397,7 +397,7 @@ msgstr "Repozitář se zálohou už na protějšku existuje." msgid "Select verified SSH public key" msgstr "Vyberte ověřený SSH veřejný klíč" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." @@ -405,33 +405,33 @@ msgstr "" "Spojení odmítnuto – ověřte, že jste zadali správné přihlašovací údaje a " "server je spuštěný." -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "Připojení odmítnuto" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "Repozitář nenalezen" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "Nesprávná šifrovací heslová fráze" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "SSH přístup odepřen" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" "Popis umístění repozitáře buď není vyplněný nebo se nejedná o existující " "repozitář záloh." -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "Existující repozitář není šifrován." -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "Úložiště {box_name}" @@ -489,7 +489,7 @@ msgid "Create Location" msgstr "Vytvořit umístění" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "Vytvořit repozitář" @@ -730,7 +730,7 @@ msgstr "Odpojení se nezdařilo!" msgid "Mounting failed" msgstr "Připojení (mount) se nezdařilo" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -742,7 +742,7 @@ msgstr "" "video dokumenty a dokumenty PDF lze prohlížet v prohlížeči. U sdílených " "souborů lze nastavit, aby po uplynutí určité doby vypršela jejich platnost." -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -753,7 +753,7 @@ msgstr "" "každé heslo lze zvolit sadu oprávnění. Po vytvoření hesla jej můžete sdílet " "s uživateli, kteří mají mít příslušná oprávnění." -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -764,39 +764,39 @@ msgstr "" "různým osobám nebo skupinám. To vám umožní později odebrat přístup jedné " "osobě nebo skupině tím, že její heslo odstraníte ze seznamu." -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "Čtení souboru, pokud je k dispozici webový odkaz na soubor" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "Vytváření nebo nahrávání souborů" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "Seznam všech souborů a jejich webových odkazů" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "Smazat soubory" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "Správa souborů: uzamčení/odemčení souborů" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "Žádné, vždy je vyžadováno heslo" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "Seznam a čtení všech souborů" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "bepasty" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "Sdílení souborů a útržků" @@ -810,7 +810,7 @@ msgstr "Oprávnění pro anonymní uživatele, kteří nezadali heslo." #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "Oprávnění" @@ -844,35 +844,35 @@ msgstr "V současné době nejsou nakonfigurována žádná hesla." #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "Heslo" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "správce" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "editor" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "prohlížející" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "Číst" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "Vytvořit" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "Výpis" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -884,35 +884,35 @@ msgstr "Výpis" msgid "Delete" msgstr "Smazat" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "správce" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "Nastavení aktualizována." -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "Při nastavování se vyskytla chyba." -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "Heslo přidáno." -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "Přidat heslo" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "Heslo smazáno." -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." @@ -920,7 +920,7 @@ msgstr "" "BIND umožňuje zveřejňovat vaše informace systému doménových názvů (DNS) na " "Internet a překládat DNS dotazy pro uživatelská zařízení na vaší síti." -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -931,32 +931,24 @@ msgstr "" "ostatních strojů na místní síti. Není také slučitelný se sdílením připojení " "k Internetu přes {box_name}." -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "BIND" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "Doménový jmenný server" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "Přeposílat na" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" "Seznam DNS serverů (oddělovaných mezerou) na které přeposílat požadavky" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "Zapnout DNSSEC" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "Zapnout zabezpečovací rozšíření systému doménových názvů" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "Obsluhované domény" @@ -988,19 +980,20 @@ msgstr "IP adresy" msgid "Refresh IP address and domains" msgstr "Obnovení IP adresy a domén" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "Nastavení aktualizováno" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -1011,7 +1004,7 @@ msgstr "" "Své e-knihy můžete ukládat do své {box_name} a číst je online nebo z " "jakéhokoli svého zařízení." -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -1026,7 +1019,7 @@ msgstr "" "čtení, záložky a zvýrazněný text. Distribuce obsahu pomocí OPDS není v " "současné době podporována." -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1034,23 +1027,23 @@ msgstr "" "K aplikaci budou mít přístup pouze uživatelé patřící do skupiny calibre. Všichni uživatelé s přístupem mohou používat všechny knihovny." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Použití knihoven e-knih Calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Knihovna e-knih" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Název nové knihovny" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1058,7 +1051,7 @@ msgstr "" "Pouze písmena anglické abecedy, číslice a znaky _ . a - bez mezer a " "speciálních znaků. Příklad: My_Library_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Knihovna s tímto názvem již existuje." @@ -1106,20 +1099,20 @@ msgstr "Přejít do knihovny %(library)s" msgid "Delete library %(library)s" msgstr "Smazat knihovnu %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Knihovna vytvořena." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Při vytváření knihovny došlo k chybě." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} smazáno." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "{name} se nepodařilo smazat: {error}" @@ -1167,7 +1160,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Správa serveru" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1175,18 +1168,18 @@ msgstr "" "Zde můžete nastavit některé obecné konfigurační možnosti, jako je název " "hostitele, název domény, domovská stránka webového serveru atd." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Obecná nastavení" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Nastavit" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1300,47 +1293,47 @@ msgstr "" "Protokoly obsahují informace o tom, kdo přistupoval k systému, a informace o " "ladění různých služeb" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Chyba při nastavování názvu stroje: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Nastavení názvu stroje" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Chyba při nastavování doménového názvu: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Nastavení doménového názvu" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Chyba při nastavování domovské stránky webového serveru: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Nastavení domovské stránky webového serveru" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Chyba při změně pokročilého režimu: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Jsou zobrazovány pokročilé aplikace a funkce" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Jsou skryté pokročilé aplikace a funkce" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1352,7 +1345,7 @@ msgstr "" "komunikační servery jej mohou používat k navázání hovoru mezi stranami, " "které se jinak nemohou vzájemně spojit." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse nebo ejabberd je " "třeba nakonfigurovat pomocí zde uvedených údajů." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Pomocník VoIP" @@ -1424,12 +1417,12 @@ msgstr "Chyba při nastavování časové zóny: {exception}" msgid "Time zone set" msgstr "Nastavení časové zóny" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "" "Deluge je BitTorrent klient který poskytuje webové uživatelské rozhraní." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1437,16 +1430,16 @@ msgstr "" "Výchozí heslo je \"deluge\", ale měli byste se přihlásit a změnit ho ihned " "po povolení této služby." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Stahovat soubory pomocí BitTorrent aplikací" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Webový klient sítě BitTorrent" @@ -1572,7 +1565,7 @@ msgstr "Výsledek" msgid "Diagnostic Test" msgstr "Diagnostické testy" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1583,7 +1576,7 @@ msgstr "" "každých 24 hodin), může být pro ostatní obtížné vás na internetu najít. To " "ostatním znemožní najít služby, které jsou poskytovány tímto {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1600,7 +1593,7 @@ msgstr "" "váš název DNS k nové IP adrese, a pokud se někdo z Internetu zeptá na váš " "název DNS, dostane odpověď s vaší aktuální IP adresou." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1613,11 +1606,11 @@ msgstr "" "aktualizaci URL na adrese freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Klient dynamické DNS" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Název dynamické domény" @@ -1748,7 +1741,7 @@ msgstr "Toto pole je povinné." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1803,7 +1796,7 @@ msgstr "Server odmítl připojení" msgid "Already up-to-date" msgstr "Již aktualizováno" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1811,7 +1804,7 @@ msgstr "" "XMPP je otevřený a standardizovaný komunikační protokol. Zde je možné " "nastavit a spustit vlastní XMPP server, zvaný ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientuživatel s přihlašovacím " "jménem {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn nebo nakonfigurujte externí " "server." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Chat server" @@ -1961,7 +1954,7 @@ msgstr "" "%(domainname)s. Doménu je možné nastavit na stránce nastavení systému." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1972,7 +1965,7 @@ msgstr "" "klientům přistupovat k poštovní schránce pomocí protokolů IMAP a POP3. " "Rspamd se zabývá nevyžádanou poštou." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1984,7 +1977,7 @@ msgstr "" "internetových služeb také omezuje odchozí poštu. Někteří po výslovné žádosti " "omezení zruší. Další informace naleznete na stránce s manuálem." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1999,7 +1992,7 @@ msgstr "" "Potřebné aliasy, jako například \"postmaster\", se vytvoří automaticky a " "ukazují na prvního uživatele-administrátora." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2007,7 +2000,7 @@ msgstr "" "Aplikace Roundcube poskytuje " "uživatelům webové rozhraní pro přístup k e-mailu." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2138,7 +2131,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "Hostitel / cíl / hodnota" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2149,7 +2142,7 @@ msgstr "" "provoz na vašem {box_name}. Zapnutá a správně nastavená brána firewall " "snižuje riziko bezpečnostních hrozeb z Internetu." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Brána firewall" @@ -2169,53 +2162,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} {details} je nedostupný pro externí sítě" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Proces služby brána firewall není spuštěný. Je třeba to napravit. Brána " -"firewall je na %(box_name)s ve výchozím stavu zapnutá. Na jakémkoli systému, " -"založeném na distribuci Debian (jako je i %(box_name)s) ji můžete spustit " -"příkazem „service firewalld start“ nebo v případě systému se systemd pomocí " -"„systemctl start firewalld“." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Služba/port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Zapnuto" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Vypnuto" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Umožněno" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Umožněno (pouze vnitřní)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Umožněno (pouze vnější)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Blokováno" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2225,13 +2204,13 @@ msgstr "" "také povolena na bráně firewall a když nějako službu vypnete, je také " "zakázána na bráně firewall." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Pokročilé" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2284,7 +2263,7 @@ msgstr "Spustit nastavení" msgid "Setup Complete" msgstr "Nastavení dokončeno" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2302,7 +2281,7 @@ msgstr "" "grafických klientů. A svoje zdrojové kódy můžete sdílet s lidmi z celého " "světa." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2310,67 +2289,67 @@ msgstr "" "Více o Git se dozvíte navštívením výuky Gitu." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Přístup do Git repozitářů pro čtení a zápis" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Jednoduché hostování Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Neplatné URL úložiště." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Neplatný název repozitáře." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "Název nového úložiště nebo adresa URL pro import stávajícího úložiště." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Popis repozitáře" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Volitelné, zobrazuje se na Gitwebu." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Jméno vlastníka repozitáře" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Neveřejný repozitář" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "K tomuto repozitáři umožnit přístup pouze pověřeným uživatelům." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Repozitář s tímto názvem už existuje." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Název repozitáře" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Řetězec písmeny a číslicemi, který jednoznačně identifikuje repozitář." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Výchozí větev" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb ji zobrazí jako výchozí větev." @@ -2414,19 +2393,19 @@ msgstr "Smazat Git repozitář %(name)s" msgid "Delete this repository permanently?" msgstr "Nevratně smazat tento repozitář?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Repozitář vytvořen." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Při vytváření úložiště došlo k chybě." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Repozitář upraven." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Upravit repozitář" @@ -2786,7 +2765,7 @@ msgstr "O {box_name}" msgid "{box_name} Manual" msgstr "Příručka k {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2798,7 +2777,7 @@ msgstr "" "anonymitu posíláním provozu zašifrovaně, skrze dobrovolníky provozovanou síť " "rozprostřenou po celém světě." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2806,26 +2785,26 @@ msgstr "" "Více informací I2P naleznete na domovské stránce projektu." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" "První navštívení poskytovaného webového rozhraní spustí proces nastavení." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Spravovat aplikaci I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Anonymní síť" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P proxy" @@ -2870,7 +2849,7 @@ msgstr "" "Soubory stahujete přidáním torrentů nebo vytvořením nového torrentu a " "sdílením souboru skrze něj." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2880,7 +2859,7 @@ msgstr "" "značkovacích jazyků, včetně Markdown, a běžné blogovací funkce, jako jsou " "komentáře a RSS kanály." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2893,15 +2872,15 @@ msgstr "" "může upravovat ty stávající. V Nastavení " "uživatele můžete tato oprávnění změnit nebo přidat nové uživatele." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "wiki a blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Zobrazit a upravit wiki aplikace" @@ -2957,42 +2936,42 @@ msgstr "" "Tato akce odebere veškeré příspěvky, stránky a komentáře včetně historie " "verzí. Opravdu chcete nenávratně smazat tuto wiki/blog?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Wiki {name} vytvořena." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Wiki se nepodařilo vytvořit: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blog {name} vytvořen." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Blog se nepodařilo vytvořit: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} dsmazáno." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "{title} se nepodařilo smazat: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" "infinoted je server pro Gobby – textový editor pro spolupráci ve skupině." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3003,11 +2982,11 @@ msgstr "" "desktopového klienta a nainstalujte ho. Poté spusťte Gobby a zvolte " "„Připojit k serveru“ a zadejte doménový název svého {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby server" @@ -3056,7 +3035,7 @@ msgstr "Janus Video Room" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Licenční informace o JavaScriptu" @@ -3076,7 +3055,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Chatovací klient" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3091,7 +3070,7 @@ msgstr "" "dokázáním, že je vlastníkem domény vůči Let's Encrypt, certifikační autoritě " "(CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3103,15 +3082,15 @@ msgstr "" "(ISRG). Před použitím služby si přečtěte Podmínky používání Let's Encrypt." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certifikáty" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Nelze testovat: Nejsou nakonfigurovány žádné domény." @@ -3176,7 +3155,7 @@ msgstr "" "Nejsou nastavené žádné domény. Nastavte je, " "aby bylo možné pro ně získat certifikát." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3185,34 +3164,34 @@ msgstr "" "Platnost certifikátu pro doménu {domain} úspěšně odvolána. Může to chvíli " "trvat, než se změna projeví." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Nepodařilo se odvolat platnost certifikátu prodoménu {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Úspěšně obdržen certifikát pro doménu {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Nepodařilo se získat certifikát pro doménu {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Certifikát pro doménu {domain} úspěšně smazán" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Nepodařilo se smazat certifikát pro doménu {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3229,7 +3208,7 @@ msgstr "" "čísla. Díky federování mohou uživatelé na daném Matrix serveru komunikovat s " "uživateli všech ostatních Matrix serverů." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3239,7 +3218,7 @@ msgstr "" "Nainstalujte aplikaci Coturn nebo " "nakonfigurujte externí server." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3347,7 +3326,7 @@ msgstr "" "Pro jeho získání přejděte na stránku Let's " "Encrypt." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3359,7 +3338,7 @@ msgstr "" "skupině. Mediawiki je možné použít pro hostování wiki webových stránek, " "poznámek nebo pro spolupráci s přáteli na projektech." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3373,7 +3352,7 @@ msgstr "" "stránce Special:" "CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3381,12 +3360,12 @@ msgstr "" "Kdokoli kdo má odkaz na tuto wiki ji může číst. Měnit obsah mohou pouze " "uživatelé, kteří jsou přihlášení." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3467,35 +3446,35 @@ msgstr "Heslo aktualizováno" msgid "Password update failed. Please choose a stronger password" msgstr "Aktualizace hesla se nezdařila. Zvolte prosím silnější heslo" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Registrace pro veřejnost otevřené" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Registrace pro veřejnost zavřené" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Soukromý režim zapnut" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Soukromý režim vypnut" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Změna výchozího vzhledu" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Nastavení doménového názvu aktualizováno" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Název webu aktualizován" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3508,11 +3487,11 @@ msgstr "" "serveru je třeba Minetest " "klient." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Pískoviště s kostkami" @@ -3561,7 +3540,7 @@ msgstr "Pokud je vypnuto, postavy hráčů nemohou zemřít nebo se zranit." msgid "Address" msgstr "Adresa" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3747,7 +3726,7 @@ msgstr "Zabezpečený shell" msgid "Services" msgstr "Služby" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3755,7 +3734,7 @@ msgstr "" "Nastavit síťová zařízení. Připojit k Internetu přes ethernet, WiFi nebo " "PPPoE. Sdílet toto připojení s ostatními zařízeními na síti." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3763,7 +3742,7 @@ msgstr "" "Zařízení spravovaná jinými metodami zde nemusí být k dispozici pro " "konfiguraci." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Sítě" @@ -4193,7 +4172,7 @@ msgstr "Upravit připojení" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Upravit" @@ -4298,7 +4277,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Metoda" @@ -4314,7 +4293,7 @@ msgstr "DNS server" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Výchozí" @@ -4327,7 +4306,7 @@ msgid "This connection is not active." msgstr "Toto připojení není aktivní." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Zabezpečení" @@ -4915,7 +4894,7 @@ msgstr "Připojení {name} smazáno." msgid "Failed to delete connection: Connection not found." msgstr "Smazání připojení se nezdařilo: Připojení nenalezeno." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4932,20 +4911,20 @@ msgstr "" "zvýšení zabezpečení a anonymity je také možné přistupovat k ostatku " "Internetu prostřednictvím {box_name}." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Připojení ke službám VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Virtuální soukromá síť" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4956,58 +4935,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Migrace na ECC" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Vaše instalace OpenVPN v současné době používá RSA. Přechod na moderní " -"kryptografii eliptických křivek zvyšuje rychlost navázání spojení a " -"bezpečnost. Tato operace je nevratná. Na většině jednodeskových počítačů by " -"měla trvat jen několik minut." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Všechny nové instalace OpenVPN na %(box_name)s budou ve výchozím nastavení " -"používat ECC. Doporučujeme provést migraci co nejdříve." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Upozornění: Stávající klientské profily budou touto operací " -"zneplatněny. Všichni uživatelé OpenVPN na %(box_name)s si musí stáhnout nové " -"profily. Pro připojení k tomuto serveru by měli být použiti klienti OpenVPN " -"kompatibilní s ECC." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migrace" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Chcete-li se připojit k síti VPN společnosti %(box_name)s, musíte si " @@ -5016,18 +4958,19 @@ msgstr "" "Doporučené klienty a pokyny k jejich konfiguraci najdete po kliknutí na " "\"Další informace...\" výše." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Profil je specifický každému z uživatelů %(box_name)s. Uchovejte ho v " "tajnosti." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Stáhnout si svůj profil" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5040,19 +4983,19 @@ msgstr "" "{box_name} nejsou dostupné ze zbytku internetu. To zahrnuje následující " "situace:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} se nachází za omezující bránou firewall." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} je připojený k (bezdrátovému) směrovači, který není ve vaší " "správě." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5060,7 +5003,7 @@ msgstr "" "Váš poskytovatel připojení vám neposkytuje vnější (veřejnou) IP adresu a " "namísto toho poskytuje připojení prostřednictvím NAT překladu." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5068,11 +5011,11 @@ msgstr "" "Váš poskytovatel připojení vám neposkytuje pevnou IP adresu a ta se proto " "mění pokaždé, když se připojíte k Internetu." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Váš poskytovatel připojení k Internetu omezuje příchozí spojení." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5085,23 +5028,23 @@ msgstr "" "pagekite, například pagekite.net. V " "budoucnu bude možná možné k tomuto účelu použít {box_name} vašeho kamaráda." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Viditelnost na veřejnosti" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite doména" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Doména serveru" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5109,31 +5052,31 @@ msgstr "" "Vyberte pagekite server, který chcete používat. Pokud to má být ten výchozí, " "zadejte „pagekite.net“." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Port serveru" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Port pagekite serveru (výchozí: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite název" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Příklad: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Neplatný kite název" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite heslo" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5141,35 +5084,35 @@ msgstr "" "Heslo přiřazené ke kite nebo výchozí heslo pro váš účet pokud není na kite " "žádné nastavené." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokol" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "vnější (frontend) port" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "vnitřní (freedombox) port" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Zapnout podřízené domény" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Uživatelem určená služba smazána" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Tato služba je již k dispozici jako standardní služba." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Uživatelem určená služba přidána" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Tato služba už existuje" @@ -5206,29 +5149,29 @@ msgstr "" "kombinace protokol/port, které zde můžete určit. Například o HTTPS na portu " "jiném, než 443 je známo, že způsobuje problémy." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Webový server (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Stránky budou k dispozici na http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Webový server (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Stránky budou k dispozici na https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Zabezpečený shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5279,8 +5222,8 @@ msgstr "" "Nyní je spuštěná instalace nebo přechod na novější verzi. Počkejte s vypínám " "či restartem na dokončení této operace." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Restartovat" @@ -5329,6 +5272,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Vypnout nyní" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5368,7 +5344,7 @@ msgstr "Webová proxy" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Přistupte {url} s proxy {proxy} na tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5385,7 +5361,7 @@ msgstr "" "více Quassel klientů z desktopu nebo mobilu může být použito pro připojení " "nebo odpojení od něj." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your desktopu a mobilních zařízení." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC klient" @@ -5409,7 +5385,7 @@ msgstr "IRC klient" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5424,7 +5400,7 @@ msgstr "" "\">podporovaná klientská aplikace. K Radicale má přístup každý uživatel " "s přihlašovacím jménem {box_name}." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5434,12 +5410,12 @@ msgstr "" "nových kalendářů a adresářů kontaktů. Nepodporuje přidávání událostí či " "kontaktů, to je třeba dělat v tomu určeném klientovi." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Kalendář a adresář kontaktů" @@ -5513,7 +5489,7 @@ msgstr "" "své uživatelské jméno. Po kliknutí na tlačítko vyhledávání se zobrazí seznam " "existujících kalendářů a adresářů." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Nastavení přístupových práv aktualizováno" @@ -5606,7 +5582,7 @@ msgstr "" "sledování různých webových stránek. Při přidávání kanálu povolte ověřování a " "použijte své přihlašovací údaje {box_name}." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Číst a přihlásit se k odběru novinek" @@ -5619,7 +5595,7 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "Generátor kanálů RSS" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5627,7 +5603,7 @@ msgstr "" "Samba umožňuje sdílet soubory a složky mezi zařízením FreedomBox a ostatními " "počítači v místní síti." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5640,11 +5616,11 @@ msgstr "" "\\{hostname} (v systému Windows) nebo smb://{hostname}.local (v systémech " "Linux a Mac). Na výběr jsou tři typy sdílených složek: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Otevřené sdílení - přístupné všem v místní síti." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5652,7 +5628,7 @@ msgstr "" "Sdílení ve skupině - přístupné pouze uživatelům FreedomBoxu, kteří jsou ve " "skupině freedombox-share." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5660,15 +5636,15 @@ msgstr "" "Domácí sdílení - každý uživatel ve skupině freedombox-share může mít svůj " "vlastní soukromý prostor." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Přístup k soukromému sdílení" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Distribuované souborové úložiště" @@ -5757,15 +5733,15 @@ msgstr "Sdílet název" msgid "Action" msgstr "Akce" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS disk" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Otevřít sdílení" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Skupinové sdílení" @@ -5791,7 +5767,7 @@ msgstr "Sdílení upraveno." msgid "Error disabling share: {error_message}" msgstr "Chyba při zakázání sdílení: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5799,7 +5775,7 @@ msgstr "" "Searx je soukromí respektující metavyhledavač na Internetu. Slučuje a " "zobrazuje výsledky z vícero vyhledávačů." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5807,39 +5783,39 @@ msgstr "" "Použitím Searx je možné se vyhnout sledování a profilování vyhledávači. Ve " "výchozím stavu neukládá žádné cookie." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Hledat na webu" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Vyhledávání na webu" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Bezpečné vyhledávání" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "Vyberte výchozí dětský filtr který uplatnit na výsledky vyhledávání." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Střední" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Přísný" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Umožnit veřejný přístup" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Umožnit, aby tato aplikace byla používána kýmkoli, kdo se k ní může dostat." @@ -6019,7 +5995,7 @@ msgstr "Záložky" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6029,7 +6005,7 @@ msgstr "" "vašeho Internetového provozu. Je možné ji použít pro obejití filtrování " "Internetu a cenzury." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6042,7 +6018,7 @@ msgstr "" "připojit k této proxy a jejich data budou šifrována a posílána " "prostřednictvím Shadowsocks serveru." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6050,43 +6026,43 @@ msgstr "" "Pro použití Shadowsocks po nastavení, nastavte SOCKS5 proxy URL adresu ve " "svém zařízení, prohlížeči nebo aplikaci na http://adresa_freedombox:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Socks5 proxy" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Doporučeno" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Server" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Název nebo IP adresa serveru" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Číslo portu serveru" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Heslo sloužící pro šifrování dat. Je třeba, aby se shodovalo s heslem " "serveru." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" "Metoda šifrování. Je třeba, aby byla stejná, jaká je nastavená na serveru." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6095,15 +6071,15 @@ msgstr "" "Sdílení umožňuje sdílet soubory a složky na vašem {box_name} přes web se " "zvolenou skupinou uživatelů." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Sdílení" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Název sdílení" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6111,29 +6087,29 @@ msgstr "" "Řetězec malými písmeny a číslicemi který jednoznačně identifikuje sdílení. " "Příklad:média." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Popis umístění které sdílet" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" "Popis umístění složky na datovém úložišti tohoto serveru které zamýšlíte " "sdílet." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Veřejné sdílení" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Zpřístupnit soubory v této složce všem, kteří mají odkaz." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Skupina uživatelů která může číst soubory na sdílení:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6141,11 +6117,11 @@ msgstr "" "Uživatelé vybraných skupin uživatelů budou moci číst soubory ve sdílené " "složce." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Sdílení s tímto názvem už existuje." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" "Sdílení by mělo být buď veřejné, nebo sdílené alespoň s jednou skupinou." @@ -6183,19 +6159,19 @@ msgstr "Sdílení přidáno." msgid "Add Share" msgstr "Přidat sdílení" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Sdílení upraveno." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Upravit sdílení" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Sdílení smazáno." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6205,7 +6181,7 @@ msgstr "" "souborového systému btrfs. Ty je možné použít pro vrácení systému do " "dřívějšího funkčního stavu v případě nechtěných změn." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6216,7 +6192,7 @@ msgstr "" "osy) a také před a po instalaci software. Nejstarší zachycené stavy budou " "automaticky mazány podle níže uvedených nastavení." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups, protože mohou být ukládány pouze na stejném oddílu, " "jako živá data. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Zachycené stavy datového úložiště" @@ -6330,7 +6306,7 @@ msgstr "Datum" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Smazat zachycené stavy" @@ -6383,57 +6359,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Vrátit k zachycenému stavu č. %(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "ručně vytvořen" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "časová osa" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Spravovat zachycené stavy" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Zachycený stav pořízen." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Nastavení zachycování stavů úložiště aktualizováno" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Chyba akce: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Označené zachycené stavy smazány" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Zachycený stav je používán. Zkuste to později." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Vráceno zpět do podoby zachyceného stavu č. {number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Pro dokončení obnovy ze zálohy je třeba systém restartovat." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Vrátit do podoby zachyceného stavu" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6445,7 +6421,7 @@ msgstr "" "spojení provádět úkoly správy, kopírovat soubory nebo spouštět ostatní " "služby." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Server zabezpečeného shellu (SSH)" @@ -6483,16 +6459,6 @@ msgstr "Algoritmus" msgid "Fingerprint" msgstr "Otisk (fingerprint)" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" -"Při připojování k serveru se ujistěte, že otisk prstu zobrazený klientem SSH " -"odpovídá jednomu z těchto otisků. Ověřování SSH s vypnutým heslem." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Ověřování SSH s povoleným heslem." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Sdružené přihlášení (SSO)" @@ -6505,7 +6471,7 @@ msgstr "Přihlášení" msgid "Logged out successfully." msgstr "Odhlášení proběhlo úspěšně." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6516,105 +6482,105 @@ msgstr "" "{box_name}. Lze zobrazit úložná zařízení, která jsou využívána, připojovat a " "odpojovat ta vyjímatelná." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Úložiště" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bajtů" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Operace se nezdařila." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Operace byla zrušena." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Toto zařízení už je odpojováno (umount)." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "Operace není podporována z důvodu chybějící podpory ovladače/nástroje." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Časový limit aplikace překročen." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "Operace by probudila disk který je v režimu hlubokého spánku." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Pokus o odpojení zařízení které je zaneprázdněno." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Operace už byla zrušena." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Chybí oprávnění pro provedení požadované operace." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Toto zařízení je už připojeno (mount)." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Zařízení není připojeno." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Není umožněno použít požadovanou volbu." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Zařízení je připojeno jiným uživatelem." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Málo místa na systémovém oddílu: {percent_used}% použito, {free_space} volné." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Málo místa na disku" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Hrozí selhání disku" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6623,39 +6589,39 @@ msgstr "" "Disk {id} hlásí, že v blízké budoucnosti pravděpodobně selže. Zkopírujte " "všechna data, dokud to ještě jde, a disk vyměňte." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Neplatný název adresáře." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Adresář neexistuje." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Cesta není adresář." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Adresář není pro uživatele čitelný." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Do adresáře nemůže uživatel zapisovat." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Adresář" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Podadresář (volitelné)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Sdílet" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Jiný adresář (uveďte níže)" @@ -6692,7 +6658,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Zvětšit kořenový oddíl" @@ -6714,30 +6680,30 @@ msgstr "" "Než budete pokračovat, zazálohujte svá data. Po provedení této operace na " "kořenovém oddílu bude k dispozici %(expandable_root_size)s dalšího prostoru." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Chyba při zvětšování oddílu: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Oddíl úspěšně zvětšen." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} je možné bezpečně odebrat." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Zařízení je možné bezpečně odebrat." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Chyba při vysouvání zařízení: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6749,7 +6715,7 @@ msgstr "" "smazání souborů na jednom zařízení bude automaticky replikováno na veškerá " "zařízení, na kterých také provozujete Syncthing." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6768,20 +6734,20 @@ msgstr "" "na {box_name} je dostupné pouze pro uživatele patřící do skupiny \"admin\" " "nebo \"syncthing-access\"." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Spravovat aplikaci Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Synchronizace souborů" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6795,7 +6761,7 @@ msgstr "" "prohlížeč Tor Browser." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6804,40 +6770,40 @@ msgstr "" "Tor SOCKS port je k dispozici na vašem {box_name} pro interní síť na TCP " "portu 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor Onion Service" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor Socks proxy" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Předávájící Tor most" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Port Tor předávání k dispozici" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 transport zaregistrován" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 transport zaregistrován" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Přistoupit k URL adrese {url} na tcp{kind} prostřednictvím Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Potvrďte použití Tor na adrese {url} na tcp{kind}" @@ -6954,11 +6920,11 @@ msgstr "Onion služba" msgid "Ports" msgstr "Porty" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Aktualizace konfigurace" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Chyba při konfiguraci aplikace: {error}" @@ -7022,7 +6988,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7031,7 +6997,7 @@ msgstr "" "Tiny Tiny RSS je čtečka a slučovač novinek (RSS/Atom), navržená pro čtení " "odkudkoli, ale s pohodlím podobným desktopové aplikaci." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7040,7 +7006,7 @@ msgstr "" "Pokud je funkce Tiny Tiny RSS povolena, může k ní přistupovat každý uživatel patřící do skupiny feed-reader." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7048,11 +7014,11 @@ msgstr "" "Při použití mobilní nebo desktopové aplikace pro Tiny Tiny RSS použijte pro " "připojení adresu URL /tt-rss-app." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Čtečka novinek" @@ -7060,13 +7026,13 @@ msgstr "Čtečka novinek" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Zjistit dostupnost a uplatnit nejnovější aktualizace a opravy zabezpečení." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7079,22 +7045,22 @@ msgstr "" "systému považován za nezbytný, provede se automaticky ve 02:00 a způsobí, že " "všechny aplikace budou krátce nedostupné." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Aktualizace software" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox aktualizován" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Nelze spustit aktualizaci distribuce" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7104,11 +7070,11 @@ msgstr "" "distribuce. Zajistěte, aby bylo volných alespoň 5 GB. Aktualizace distribuce " "se bude opakovat po 24 hodinách, pokud je povolena." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Zahájena aktualizace distribuce" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7274,49 +7240,51 @@ msgid "" "This will attempt to upgrade the system from stable to testing. It " "is meant only for development use." msgstr "" +"Tím se pokusíte upgradovat systém ze stabilního na testovací. Je " +"určen pouze pro vývojové použití." #: plinth/modules/upgrades/templates/upgrades_configure.html:150 msgid "Test distribution upgrade now" msgstr "Otestujte aktualizaci distribuce" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Chyba při nastavování bezobslužných aktualizací: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatické aktualizace zapnuty" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatické aktualizace vypnuty" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Upgrade distribuce povoleno" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Upgrade distribuce zakázáno" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Proces přechodu na novější verze zahájen." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Spouštění přechodu na novější verzi se nezdařilo." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Aktivovány časté aktualizace funkcí." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Zahájení testu aktualizace distribuce." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7327,7 +7295,7 @@ msgstr "" "aby uživatelský účet byl součástí skupiny, která uživatele opravňuje k " "přístupu k aplikaci." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7339,15 +7307,15 @@ msgstr "" "nebo nastavení systému však mohou měnit pouze uživatelé skupiny admin." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Uživatelé a skupiny" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Přístup ke všem službám a nastavení systému" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Zkontrolujte LDAP položku „{search_item}“" @@ -7367,21 +7335,21 @@ msgid "" msgstr "" "Požadováno. Nejvýše 150 znaků. Pouze anglická písmena, číslice a @/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Autorizační heslo" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "Zadejte heslo uživatele \"{user}\" pro autorizaci změn účtu." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Neplatné heslo." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7395,12 +7363,12 @@ msgstr "" "skupině admin se budou moci přihlásit ke všem službám. Mohou se také " "přihlašovat do systému prostřednictvím SSH a mají práva správce (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Vytvoření uživatele LDAP se nezdařilo: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Nepodařilo se přidat nového uživatele do skupiny {group}: {error}" @@ -7419,41 +7387,41 @@ msgstr "" "systému i bez zadávání hesla. Klíčů je možné vložit vícero, každý na vlastní " "řádek. Prázdné řádky a ty, které začínají na znak # budou ignorovány." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Přejmenování LDAP uživatele se nezdařilo." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Odebrání uživatele ze skupiny se nezdařilo." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Přidání uživatele do skupiny se nezdařilo." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Nepodařilo se vložit SSH klíče." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Nepodařilo se změnit stav uživatele." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Změna hesla LDAP uživatele se nezdařila." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Nepodařilo se přidat nového uživatele do skupiny admin: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Nepodařilo se omezit přístup ke konzole: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Uživatelský účet vytvořen, není jste jím přihlášeni" @@ -7470,12 +7438,12 @@ msgstr "Uložit heslo" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Vytvořit uživatele" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Smazat uživatele" @@ -7516,13 +7484,19 @@ msgid "The following administrator accounts exist in the system." msgstr "V systému existují následující účty správců." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Odstraňte tyto účty z příkazového řádku a obnovte stránku, abyste vytvořili " "účet, který je použitelný s %(box_name)s. V příkazovém řádku spusťte příkaz " @@ -7531,7 +7505,7 @@ msgstr "" "přeskočte." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Uživatelé" @@ -7564,34 +7538,34 @@ msgstr "" msgid "Save Changes" msgstr "Uložit změny" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Uživatel %(username)s vytvořen." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Uživatel %(username)s aktualizován." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Upravit uživatele" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Uživatel {user} smazán." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Smazání LDAP uživatele se nezdařilo." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Změnit heslo" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Heslo úspěšně změněno." @@ -7926,7 +7900,7 @@ msgstr "Odstranit připojení k serveru" msgid "Server deleted." msgstr "Server smazán." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7940,7 +7914,7 @@ msgstr "" "Administrační rozhraní a vytvořené webové stránky jsou vhodné pro mobilní " "zařízení." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7953,7 +7927,7 @@ msgstr "" "názvem domény. Povolte trvalé odkazy v rozhraní správce pro lepší adresy URL " "vašich stránek a příspěvků." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -7964,7 +7938,7 @@ msgstr "" "přidejte si stranu administrace do " "záložek." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -7974,12 +7948,12 @@ msgstr "" "rozhraní správce. Další zásuvné moduly nebo témata lze instalovat a " "aktualizovat na vlastní riziko." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Webové stránky a blog" @@ -7996,7 +7970,7 @@ msgstr "" "WordPress pouze správcům. Povolte pouze po provedení počátečního nastavení " "WordPressu." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8018,7 +7992,7 @@ msgstr "" "určitém místě. Jednotlivé fotografie lze sdílet s ostatními odesláním " "přímého odkazu." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8029,11 +8003,11 @@ msgstr "" "další uživatele musí být vytvořeny účty jak v {box_name}, tak v Zoph se " "stejným uživatelským jménem." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Organizér fotografií" @@ -8086,96 +8060,92 @@ msgstr "Čeká na spuštění: {name}" msgid "Finished: {name}" msgstr "Dokončeno: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Balíček {expression} není k dispozici pro instalaci" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Balíček {package_name} je nejnovější verze ({latest_version})" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "Chyba při spuštění apt-get" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "Instalace" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "stahování" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "změna média" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "soubor s nastaveními: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Časový limit čekání na správce balíčků" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Instalace aplikací" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Aktualizace aplikací" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Chyba instalace aplikace: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Chyba aktualizace aplikace: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Chyba při instalaci aplikace: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Chyba při aktualizaci aplikace: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "Aplikace nainstalována." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "Aplikace aktualizována" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Odinstalování aplikace" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Chyba odinstalace aplikace: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Chyba při odinstalaci aplikace: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "Aplikace odinstalována." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Aktualizace balíčků aplikací" @@ -8233,53 +8203,54 @@ msgstr "Instalace" msgid "Service %(service_name)s is not running." msgstr "Služba %(service_name)s není spuštěná." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Základní funkce a webové rozhraní pro %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Domů" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Domů" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Aplikace" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Aplikace" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Systém" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Systém" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Změnit heslo" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Vypnout" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Odhlásit" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Vyberte jazyk" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Přihlásit" @@ -8569,6 +8540,77 @@ msgstr "před odinstalací {app_id}" msgid "Gujarati" msgstr "gudžarátština" +#~ msgid "Enable DNSSEC" +#~ msgstr "Zapnout DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Zapnout zabezpečovací rozšíření systému doménových názvů" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Proces služby brána firewall není spuštěný. Je třeba to napravit. Brána " +#~ "firewall je na %(box_name)s ve výchozím stavu zapnutá. Na jakémkoli " +#~ "systému, založeném na distribuci Debian (jako je i %(box_name)s) ji " +#~ "můžete spustit příkazem „service firewalld start“ nebo v případě systému " +#~ "se systemd pomocí „systemctl start firewalld“." + +#~ msgid "Migrate to ECC" +#~ msgstr "Migrace na ECC" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Vaše instalace OpenVPN v současné době používá RSA. Přechod na moderní " +#~ "kryptografii eliptických křivek zvyšuje rychlost navázání spojení a " +#~ "bezpečnost. Tato operace je nevratná. Na většině jednodeskových počítačů " +#~ "by měla trvat jen několik minut." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Všechny nové instalace OpenVPN na %(box_name)s budou ve výchozím " +#~ "nastavení používat ECC. Doporučujeme provést migraci co nejdříve." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Upozornění: Stávající klientské profily budou touto operací " +#~ "zneplatněny. Všichni uživatelé OpenVPN na %(box_name)s si musí stáhnout " +#~ "nové profily. Pro připojení k tomuto serveru by měli být použiti klienti " +#~ "OpenVPN kompatibilní s ECC." + +#~ msgid "Migrate" +#~ msgstr "Migrace" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "" +#~ "Při připojování k serveru se ujistěte, že otisk prstu zobrazený klientem " +#~ "SSH odpovídá jednomu z těchto otisků. Ověřování SSH s vypnutým heslem." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Ověřování SSH s povoleným heslem." + +#~ msgid "Error running apt-get" +#~ msgstr "Chyba při spuštění apt-get" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Základní funkce a webové rozhraní pro %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Síťová připojení" diff --git a/plinth/locale/da/LC_MESSAGES/django.po b/plinth/locale/da/LC_MESSAGES/django.po index fdebd06e0..f10c4e811 100644 --- a/plinth/locale/da/LC_MESSAGES/django.po +++ b/plinth/locale/da/LC_MESSAGES/django.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: FreedomBox UI\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Danish calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1049,29 +1042,29 @@ msgstr "" "Kun brugere der tilhører calibre-gruppen har adgang til appen. Alle " "brugere med adgang kan benytte alle samlingerne." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Brug calibre e-bogssamlinger" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-bogssamling" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Den nye samlings navn" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "En samling med dette navn eksisterer allerede." @@ -1119,20 +1112,20 @@ msgstr "Tilgå samlingen %(library)s" msgid "Delete library %(library)s" msgstr "Slet samlingen %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Samling oprettet." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Der opstod en fejl under oprettelse af samlingen." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} slettet." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Kunne ikke slette {name}: {error}" @@ -1180,7 +1173,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Serveradministration" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1188,18 +1181,18 @@ msgstr "" "Her kan du konfigurere nogle generelle indstillinger såsom værtsnavn, " "domænenavn, webserverens hjemmeside osv." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Generel Konfiguration" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Konfigurer" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1312,47 +1305,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Kunne ikke sætte værtsnavn: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Værtsnavn gemt" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Kunne ikke sætte domænenavn: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Domænenavn gemt" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Fejl ved indstilling af webserverens hjemmeside: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Webserverens hjemmeside er blevet indstillet" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Fejl ved skift til avanceret tilstand: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Viser avancerede applikationer og funktionalitet" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Skjuler avancerede applikationer og funktionalitet" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1364,7 +1357,7 @@ msgstr "" "WebRTC, SIP og andre kommunikationsservere kan bruge dette til at oprette et " "opkald mellem parter der ellers ikke kan oprette forbindelse til hinanden." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, fuzzy, python-brace-format #| msgid "" #| "It is not meant to be used directly by users. Servers such as matrix-" @@ -1377,11 +1370,11 @@ msgstr "" "Den er ikke beregnet til at blive anvendt direkte af brugerne. Servere såsom " "matrix-synapse skal konfigureres med detaljerne som er angivet her." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP-hjælper" @@ -1439,11 +1432,11 @@ msgstr "Kunne ikke sætte tidszone: {exception}" msgid "Time zone set" msgstr "Tidszone gemt" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge er en BitTorrent-klient som har et webbaseret brugerinterface." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1451,16 +1444,16 @@ msgstr "" "Standardkodeordet er 'deluge', men du bør logge ind og ændre det så snart du " "har aktiveret denne tjeneste." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Download filer ved hjælp af BitTorrent-applikationer" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent Webklient" @@ -1587,7 +1580,7 @@ msgstr "Resultat" msgid "Diagnostic Test" msgstr "Diagnostisk Test" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1598,7 +1591,7 @@ msgstr "" "døgnet), kan det være svært for andre at finde dig på internettet. Dette vil " "forhindre andre i at finde de tjenester denne {box_name} udbyder." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1615,7 +1608,7 @@ msgstr "" "opdatere dit DNS-navn med den nye IP-adresse, således at hvis nogen på " "internettet spørger til adressen vil de få din aktuelle IP-adresse." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 #, fuzzy #| msgid "" #| "If you are looking for a free dynamic DNS account, you may find a free " @@ -1634,11 +1627,11 @@ msgstr "" "datasystems24.net eller du kan få en gratis URL-baseret tjeneste på freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Dynamisk DNS Klient" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dynamisk domænenavn" @@ -1772,7 +1765,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1841,7 +1834,7 @@ msgstr "Slet forbindelse" msgid "Already up-to-date" msgstr "Seneste opdatering" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1849,7 +1842,7 @@ msgstr "" "XMPP er en åben og standardiseret kommunikationsprotokol. Her kan du " "aktivere og konfigurere din XMPP-server, kaldet ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client bruger med adgang til {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Chatserver" @@ -1994,14 +1987,14 @@ msgstr "" "vil se ud som brugernavn@%(domainname)s. Du kan konfigurere systemets " "domæne på Konfigurer siden." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2009,7 +2002,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2019,13 +2012,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2168,7 +2161,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2179,7 +2172,7 @@ msgstr "" "på din{box_name}. At holde en firewall aktiveret og velkonfigureret " "reducerer risikoen for sikkerhedstrusler fra internettet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2199,52 +2192,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} ({details}) er ikke tilgængelig for eksterne netværk" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Firewall-tjenesten er ikke aktiv. Vær venlig at starte den. Den er som " -"standard aktiveret på %(box_name)s. På Debian-baserede systemer (som " -"%(box_name)s er) kan den startes med kommandoen 'service firewalld start' " -"eller hvis systemet bruger systemd 'systemctl start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Tjeneste/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Aktiveret" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Deaktiveret" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Tilladt" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Tilladt (kun internt)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Tilladt (kun eksternt)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Blokeret" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2254,13 +2234,13 @@ msgstr "" "også blive åbnet i firewallen, og når du deaktiverer en tjeneste blokeres " "den igen." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Avanceret" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2313,7 +2293,7 @@ msgstr "Start Konfiguration" msgid "Setup Complete" msgstr "Konfiguration Færdig" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2331,7 +2311,7 @@ msgstr "" "klient til kommandolinjen eller med flere tilgængelige grafiske klienter. Og " "så kan du dele din kode med mennesker over hele kloden." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2339,79 +2319,79 @@ msgstr "" "For at lære med om hvordan du bruger Git kan du besøge Git-vejledningen." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Læse- og skriveadgang til Git-repositorier" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Simpel Git-hosting" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Ugyldig URL til repositorie." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "Ugyldigt værtsnavn" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 #, fuzzy #| msgid "packages not found" msgid "Repository's owner name" msgstr "pakker ikke fundet" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create User" msgid "Private repository" msgstr "Opret Bruger" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 #, fuzzy #| msgid "This service already exists" msgid "A repository with this name already exists." msgstr "Denne tjeneste eksisterer allerede" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Create User" msgid "Name of the repository" msgstr "Opret Bruger" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default" msgid "Default branch" msgstr "Standard" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2466,25 +2446,25 @@ msgstr "Slet Wiki eller Blog %(name)s" msgid "Delete this repository permanently?" msgstr "Slet bruger permanent?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 #, fuzzy #| msgid "packages not found" msgid "Repository created." msgstr "pakker ikke fundet" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 #, fuzzy #| msgid "An error occurred during configuration." msgid "An error occurred while creating the repository." msgstr "Der opstod en fejl under konfigurationen." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 #, fuzzy #| msgid "packages not found" msgid "Repository edited." msgstr "pakker ikke fundet" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Create User" msgid "Edit repository" @@ -2829,7 +2809,7 @@ msgstr "Om {box_name}" msgid "{box_name} Manual" msgstr "{box_name} Brugervejledning" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2837,7 +2817,7 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 #, fuzzy #| msgid "" #| "For more information about the %(box_name)s project, see the %(box_name)s Wiki-siden." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy #| msgid "Enable application" msgid "Manage I2P application" msgstr "Aktiver applikation" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 #, fuzzy #| msgid "Tor Anonymity Network" msgid "Anonymity Network" msgstr "Tor Anonymiseringstjeneste" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2908,7 +2888,7 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 #, fuzzy #| msgid "" #| "ikiwiki is a simple wiki and blog application. It supports several " @@ -2925,7 +2905,7 @@ msgstr "" "kommentarer og RSS-feeds. Når aktiveret, vil blogge og wikier være " "tilgængelige på /ikiwiki." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2934,17 +2914,17 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 #, fuzzy #| msgid "Wiki & Blog" msgid "Wiki and Blog" msgstr "Wiki & Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 #, fuzzy #| msgid "Services and Applications" msgid "View and edit wiki applications" @@ -3002,43 +2982,43 @@ msgstr "" "Denne handling fjerner alle artikler, sider og kommentater inklusiv al " "historik. Slet denne wiki eller blog permanent?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Wiki {name} oprettet." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Kunne ikke oprette wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blog {name} oprettet." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Kunne ikke oprette blog: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, fuzzy, python-brace-format #| msgid "{name} deleted." msgid "{title} deleted." msgstr "{name} slettet." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, fuzzy, python-brace-format #| msgid "Could not delete {name}: {error}" msgid "Could not delete {title}: {error}" msgstr "Kunne ikke slette {name}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3046,11 +3026,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 #, fuzzy #| msgid "Web Server" msgid "Gobby Server" @@ -3098,7 +3078,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -3118,7 +3098,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "IRC-klient (Quassel)" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "A digital certficate allows users of a web service to verify the identity " @@ -3139,7 +3119,7 @@ msgstr "" "Dette gøres ved at bekræfte overfor Let's Encrypt, en certifikat-autoritet " "(CA), at den har ejerskab over domænet." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 #, fuzzy #| msgid "" #| "Let's Encrypt is a free, automated, and open certificate authority, run " @@ -3159,17 +3139,17 @@ msgstr "" "org/repository/\">Let's Encrypts abonnementsbetingelser inden tjenesten " "tages i anvendelse." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 #, fuzzy #| msgid "Certificate Status" msgid "Certificates" msgstr "Certifikat Status" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3240,7 +3220,7 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, fuzzy, python-brace-format #| msgid "Certificate successfully revoked for domain {domain}" msgid "" @@ -3248,37 +3228,37 @@ msgid "" "moments to take effect." msgstr "Certifikatet for domænet {domain} blev trukket tilbage" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Fejl ved tilbagetrækning af certifikatet for domænet {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Certifikatet for domænet {domain} blev erhvervet" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" "Fejl ved forsøg på at erhverve certifikatet for domænet {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, fuzzy, python-brace-format #| msgid "Certificate successfully revoked for domain {domain}" msgid "Certificate successfully deleted for domain {domain}" msgstr "Certifikatet for domænet {domain} blev trukket tilbage" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, fuzzy, python-brace-format #| msgid "Failed to revoke certificate for domain {domain}: {error}" msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Fejl ved tilbagetrækning af certifikatet for domænet {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3288,14 +3268,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3385,7 +3365,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3393,7 +3373,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3402,18 +3382,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3494,49 +3474,49 @@ msgstr "Kodeord" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 #, fuzzy #| msgid "Application enabled" msgid "Public registrations enabled" msgstr "Applikation aktiveret" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 #, fuzzy #| msgid "Application disabled" msgid "Public registrations disabled" msgstr "Applikation deaktiveret" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 #, fuzzy #| msgid "PageKite enabled" msgid "Private mode enabled" msgstr "PageKite aktiveret" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy #| msgid "PageKite disabled" msgid "Private mode disabled" msgstr "PageKite deaktiveret" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 #, fuzzy #| msgid "Setting unchanged" msgid "Default skin changed" msgstr "Indstilling uændret" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "Domænenavn gemt" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "Domænenavn gemt" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3549,11 +3529,11 @@ msgstr "" "For at forbinde til serveren skal der bruges en Minetest klient." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 #, fuzzy #| msgid "Block Sandbox (Minetest)" msgid "Block Sandbox" @@ -3606,7 +3586,7 @@ msgstr "" msgid "Address" msgstr "Adresse" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3793,19 +3773,19 @@ msgstr "Secure Shell" msgid "Services" msgstr "Tjeneste" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Netværk" @@ -4190,7 +4170,7 @@ msgstr "Rediger Forbindelse" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Rediger" @@ -4295,7 +4275,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Metode" @@ -4311,7 +4291,7 @@ msgstr "DNS-server" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Standard" @@ -4324,7 +4304,7 @@ msgid "This connection is not active." msgstr "Denne forbindelse er ikke aktiv." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Sikkerhed" @@ -4922,7 +4902,7 @@ msgstr "Slettede forbindelse {name}." msgid "Failed to delete connection: Connection not found." msgstr "Kunne ikke slette forbindelse: Forbindelse ikke fundet." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4939,26 +4919,26 @@ msgstr "" "af {box_name}. Du kan også tilgå resten af internettet igennem {box_name} " "for øget sikkerhed og anonymitet." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection Type" msgid "Connect to VPN services" msgstr "Forbindelsestype" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 #, fuzzy #| msgid "OpenVPN" msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 #, fuzzy #| msgid "Virtual Private Network (OpenVPN)" msgid "Virtual Private Network" msgstr "Virtuelt Privat Netværk (OpenVPN)" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4968,45 +4948,11 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -#, fuzzy -#| msgid "Mode" -msgid "Migrate" -msgstr "Tilstand" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, fuzzy, python-format #| msgid "" #| "To connect to %(box_name)s's VPN, you need to download a profile and feed " @@ -5017,8 +4963,8 @@ msgstr "Profil" #| "how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "For at forbinde til %(box_name)ss VPN skal du downloade en profil og " @@ -5028,18 +4974,19 @@ msgstr "" "Brugervejledning - OpenVPN\">dokumentation om anbefalede klienter og " "instruktioner til opsætning af dem." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Profilen er dannet specifikt til hver bruger af %(box_name)s. Hold den " "hemmelig." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Hent min profil" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5052,19 +4999,19 @@ msgstr "" "hvis {box_name} tjenester ikke kan nås fra resten af internettet. Dette " "inkluderer de følgende situationer:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} er bag en restriktiv firewall." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} er forbundet til en (trådløs) router som du ikke selv " "kontrollerer." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5072,7 +5019,7 @@ msgstr "" "Din internetudbyder tildeler dig ikke en ekstern IP-adresse, men giver dig " "forbindelse gennem NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 #, fuzzy #| msgid "" #| "Your ISP does not provide you a static IP address and your IP address " @@ -5084,11 +5031,11 @@ msgstr "" "Din internetudbyder tildeler dig ikke en fast IP-adresse, og din IP-adresse " "ændres hver gang du fobinder til nettet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Din internetudbyder begrænser indgående forbindelser." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, fuzzy, python-brace-format #| msgid "" #| "PageKite works around NAT, firewalls and IP-address limitations by using " @@ -5108,29 +5055,29 @@ msgstr "" "net. I fremtiden vil det måske blive muligt at bruge din vens {box_name} " "til dette." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 #, fuzzy #| msgid "Pagekite" msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 #, fuzzy #| msgid "Public Visibility (PageKite)" msgid "Public Visibility" msgstr "Offentlig Tilgængelighed (PageKite)" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 #, fuzzy #| msgid "PageKite Account" msgid "PageKite Domain" msgstr "PageKite-konto" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Serverdomæne" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5138,31 +5085,31 @@ msgstr "" "Vælg din PageKite-server. Brug \"pagekite.net\" hvis du vil bruge " "standardserveren fra pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Serverport" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "PageKite-serverport (standard: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite-navn" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Eksempel: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Ugyldigt kite-name" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite-hemmelighed" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5170,27 +5117,27 @@ msgstr "" "En hemmelighed tilknyttet denne kite, eller standard-hemmeligheden for din " "konto hvis der ikke er defineret nogen for denne kite." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokol" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "ekstern (WAN) port" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "intern (FreedomBox) port" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Aktiver Subdomæner" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Brugerdefineret tjeneste slettet" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 #, fuzzy #| msgid "" #| "This service is available as a standard service. Please use the " @@ -5200,11 +5147,11 @@ msgstr "" "Denne tjeneste er tilgængelig som en standardtjeneste. Brug venligst siden " "\"Standardtjenester\" for at aktivere den." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Tilføjet brugerdefineret tjeneste" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Denne tjeneste eksisterer allerede" @@ -5246,29 +5193,29 @@ msgstr "" "her. For eksempel er HTTPS på andre porte end 443 kendt for at give " "problemer." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Webserver (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Siden vil være tilgængelig på http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Webserver (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Siden vil være tilgængelig på https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5314,8 +5261,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 #, fuzzy #| msgid "Restart Now" msgid "Restart" @@ -5365,6 +5312,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Sluk Nu" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Enable Privoxy" +msgid "Privacy" +msgstr "Aktiver Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5415,7 +5395,7 @@ msgstr "Privoxy Webproxy" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Tilgå {url} med proxy {proxy} ved brug af tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5432,7 +5412,7 @@ msgstr "" "kontinuerligt online, og du vil kunne bruge en eller flere Quassel-klienter " "fra en computer eller en mobil til at forbinde til den." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your computer og mobile enhed er tilgængelige." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 #, fuzzy #| msgid "Quassel IRC Client" msgid "IRC Client" @@ -5458,7 +5438,7 @@ msgstr "Quassel IRC-klient" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5479,19 +5459,19 @@ msgstr "" "carddav-clients\">understøttet klient-applikation. Radicale kan tilgås " "af enhver bruger der har et log ind til {box_name}." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 #, fuzzy #| msgid "Calendar and Addressbook (Radicale)" msgid "Calendar and Addressbook" @@ -5554,7 +5534,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 #, fuzzy #| msgid "Configuration updated" msgid "Access rights configuration updated" @@ -5653,7 +5633,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5668,13 +5648,13 @@ msgstr "Bro" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5683,31 +5663,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Network Time Server" msgid "Network File Storage" @@ -5795,17 +5775,17 @@ msgstr "Kite-navn" msgid "Action" msgstr "Handlinger" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS disk" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 #, fuzzy #| msgid "Add Service" msgid "Open Share" msgstr "Tilføj Service" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 #, fuzzy #| msgid "Add Service" msgid "Group Share" @@ -5841,57 +5821,57 @@ msgstr "{name} slettet." msgid "Error disabling share: {error_message}" msgstr "Kunne ikke installere applikation: {error}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 #, fuzzy #| msgid "Web Server" msgid "Web Search" msgstr "Webserver" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 #, fuzzy #| msgid "Save Services" msgid "Safe Search" msgstr "Gem Tjenester" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 #, fuzzy #| msgid "Mode" msgid "Moderate" msgstr "Tilstand" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -6073,14 +6053,14 @@ msgstr "Bogmærker (Shaarli)" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6089,107 +6069,107 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 #, fuzzy #| msgid "Service" msgid "Server" msgstr "Tjeneste" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 #, fuzzy #| msgid "Server port" msgid "Server port number" msgstr "Serverport" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 #, fuzzy #| msgid "Enable Shaarli" msgid "Sharing" msgstr "Aktiver Shaarli" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 #, fuzzy #| msgid "Publish Key" msgid "Public share" msgstr "Distribuer Nøgle" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 #, fuzzy #| msgid "This service already exists" msgid "A share with this name already exists." msgstr "Denne tjeneste eksisterer allerede" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -6232,30 +6212,30 @@ msgstr "" msgid "Add Share" msgstr "Tilføj Service" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 #, fuzzy #| msgid "Edit User" msgid "Edit Share" msgstr "Rediger Bruger" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 #, fuzzy #| msgid "{name} deleted." msgid "Share deleted." msgstr "{name} slettet." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6263,14 +6243,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 #, fuzzy #| msgid "Create User" msgid "Storage Snapshots" @@ -6378,7 +6358,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 #, fuzzy #| msgid "Delete %(name)s" msgid "Delete Snapshots" @@ -6430,65 +6410,65 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Library created." msgid "manually created" msgstr "Samling oprettet." -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 #, fuzzy #| msgid "Create User" msgid "Manage Snapshots" msgstr "Opret Bruger" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 #, fuzzy #| msgid "Configuration updated" msgid "Storage snapshots configuration updated" msgstr "Konfiguration opdateret" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Fejl under handling: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 #, fuzzy #| msgid "Delete %(name)s" msgid "Deleted selected snapshots" msgstr "Slet %(name)s" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6496,7 +6476,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Secure Shell (SSH) Server" @@ -6535,14 +6515,6 @@ msgstr "" msgid "Fingerprint" msgstr "SSH-fingeraftryk" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6557,7 +6529,7 @@ msgstr "Log ind" msgid "Logged out successfully." msgstr "Kodeord blev ændret." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6565,164 +6537,164 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 #, fuzzy #| msgid "reStore" msgid "Storage" msgstr "reStore" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, fuzzy, python-brace-format #| msgid "{disk_size} bytes" msgid "{disk_size:.1f} bytes" msgstr "{disk_size} bytes" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, fuzzy, python-brace-format #| msgid "{disk_size} KiB" msgid "{disk_size:.1f} KiB" msgstr "{disk_size} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, fuzzy, python-brace-format #| msgid "{disk_size} MiB" msgid "{disk_size:.1f} MiB" msgstr "{disk_size} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, fuzzy, python-brace-format #| msgid "{disk_size} GiB" msgid "{disk_size:.1f} GiB" msgstr "{disk_size} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, fuzzy, python-brace-format #| msgid "{disk_size} TiB" msgid "{disk_size:.1f} TiB" msgstr "{disk_size} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 #, fuzzy #| msgid "repro service is running" msgid "The device is already unmounting." msgstr "repro-tjenesten er aktiv" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 #, fuzzy #| msgid "This service already exists" msgid "The device is already mounted." msgstr "Denne tjeneste eksisterer allerede" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 #, fuzzy #| msgid "repro service is not running" msgid "The device is not mounted." msgstr "repro-tjenesten er ikke aktiv" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "Ugyldigt værtsnavn" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 #, fuzzy #| msgid "Download directory" msgid "Path is not a directory." msgstr "Download-mappe" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 #, fuzzy #| msgid "Download directory" msgid "Directory" msgstr "Download-mappe" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 #, fuzzy #| msgid "Add Service" msgid "Share" msgstr "Tilføj Service" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6761,7 +6733,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Udvid Rod-partition" @@ -6782,30 +6754,30 @@ msgstr "" "Efter denne operation, vil der være yderligere %(expandable_root_size)s fri " "diskplads på din rod-partition." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Kunne ikke udvidde partition: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Partition blev udviddet." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6813,7 +6785,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6825,22 +6797,22 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 #, fuzzy #| msgid "Install this application?" msgid "Administer Syncthing application" msgstr "Installer denne applikation?" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6854,7 +6826,7 @@ msgstr "" "du bruger Tor-browseren." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, fuzzy, python-brace-format #| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." msgid "" @@ -6862,42 +6834,42 @@ msgid "" "TCP port 9050." msgstr "En Tor SOCKS-port er tilgængelig på din %(box_name)s TCP-port 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 #, fuzzy #| msgid "Tor Hidden Service" msgid "Tor Onion Service" msgstr "Tor Skjult Tjeneste" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor Bridge Relay" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor videresendelsesport tilgængelig" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 transport registreret" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 transport registreret" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Tilgå URL {url} ved brug af tcp{kind} via Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Bekræft brug af Tor på {url} ved brug af tcp{kind}" @@ -7010,13 +6982,13 @@ msgstr "Skjult Tjeneste" msgid "Ports" msgstr "Porte" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Der opstod en fejl under konfigurationen." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -7079,7 +7051,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission BitTorrent" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7089,7 +7061,7 @@ msgstr "" "er designet til at læse nyheder på farten, men samtidig føles så meget som " "en rigtig desktop-applikation som muligt." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS will be available from /" @@ -7101,17 +7073,17 @@ msgstr "" "Når aktiveret, vil Tiny Tiny RSS være tilgængelige på stien /tt-rss på webserveren." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 #, fuzzy #| msgid "News Feed Reader (Tiny Tiny RSS)" msgid "News Feed Reader" @@ -7121,12 +7093,12 @@ msgstr "Nyhedsstrømlæser (Tiny Tiny RSS)" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7134,8 +7106,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -7143,30 +7115,30 @@ msgstr "" msgid "Software Update" msgstr "Softwareopdateringer" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox Manual" msgid "FreedomBox Updated" msgstr "FreedomBox Brugervejledning" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution update started" msgstr "Automatisk opdatering deaktiveret" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7352,58 +7324,58 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Automatisk opdatering aktiveret" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" "Kunne ikke konfigurere automatisk opdatering (unattended-upgrades): {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatisk opdatering aktiveret" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatisk opdatering deaktiveret" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Distribution upgrade enabled" msgstr "Automatisk opdatering aktiveret" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution upgrade disabled" msgstr "Automatisk opdatering deaktiveret" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Opdateringsprocessen er startet." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Kunne ikke starte opdatering." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Starting distribution upgrade test." msgstr "Automatisk opdatering aktiveret" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7411,15 +7383,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Brugere og Grupper" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Kontrol af LDAP-konfiguration \"{search_item}\"" @@ -7439,25 +7411,25 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Account" msgid "Authorization Password" msgstr "Administratorkonto" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "Vis kodeord" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 #, fuzzy #| msgid "" #| "Select which services should be available to the new user. The user will " @@ -7479,13 +7451,13 @@ msgstr "" "tjenester. De kan også logge ind på systemet gennem SSH og har " "administratorprivilegier (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, fuzzy, python-brace-format #| msgid "Creating LDAP user failed." msgid "Creating LDAP user failed: {error}" msgstr "Kunne ikke oprette LDAP-bruger." -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, fuzzy, python-brace-format #| msgid "Failed to add new user to {group} group." msgid "Failed to add new user to {group} group: {error}" @@ -7505,46 +7477,46 @@ msgstr "" "sikkert ind på systemet uden et kodeord. Der kan defineres flere nøgler, en " "på hver linje. Tomme linjer og linjer som starter med # bliver ignoreret." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Kunne ikke omdøbe LDAP-bruger." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Kunne ikke fjerne bruger fra gruppe." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Kunne ikke tilføje bruger til gruppe." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add user to group." msgid "Failed to change user status." msgstr "Kunne ikke tilføje bruger til gruppe." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Kunne ikke ændre LDAP-kodeord." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, fuzzy, python-brace-format #| msgid "Failed to add new user to admin group." msgid "Failed to add new user to admin group: {error}" msgstr "Kunne ikke tilføje ny bruger til admin-gruppen." -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, fuzzy, python-brace-format #| msgid "Failed to obtain certificate for domain {domain}: {error}" msgid "Failed to restrict console access: {error}" msgstr "" "Fejl ved forsøg på at erhverve certifikatet for domænet {domain}: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Brugerkonto oprettet, du er nu logget ind" @@ -7561,12 +7533,12 @@ msgstr "Gem Kodeord" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Opret Bruger" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Slet Bruger" @@ -7611,17 +7583,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Brugere" @@ -7654,34 +7626,34 @@ msgstr "" msgid "Save Changes" msgstr "Gem Ændringer" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Bruger %(username)s oprettet." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Bruger %(username)s opdateret." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Rediger Bruger" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Brugeren {user} slettet." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Kunne ikke slette LDAP-bruger." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Ændr kodeord" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Kodeord blev ændret." @@ -8042,7 +8014,7 @@ msgstr "Slet Forbindelse" msgid "Server deleted." msgstr "{name} slettet." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8051,7 +8023,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8060,28 +8032,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "Adresse" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki & Blog" msgid "Website and Blog" @@ -8099,7 +8071,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8112,7 +8084,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8120,11 +8092,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -8177,114 +8149,108 @@ msgstr "" msgid "Finished: {name}" msgstr "Tjeneste ikke aktiv: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing Backups" -msgid "Error running apt-get" -msgstr "Eksisterende sikkerhedskopier" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "Installerer" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "downloader" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "medie-ændring" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "konfigurationsfil: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Installer applikationer" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Kunne ikke installere applikation: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Kunne ikke installere applikation: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Kunne ikke installere applikation: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Kunne ikke installere applikation: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Applikation installeret." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Seneste opdatering" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Installer applikationer" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Kunne ikke installere applikation: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Kunne ikke installere applikation: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Applikation installeret." -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8353,58 +8319,58 @@ msgstr "Installation" msgid "Service %(service_name)s is not running." msgstr "Tjenestesøgningstjenesten er ikke aktiv" -#: plinth/templates/base.html:30 -#, fuzzy, python-format -#| msgid "Plinth administrative interface for the %(box_name)s" -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Plinth administrationsværktøj til %(box_name)s" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Apps" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Apps" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " System" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "System" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Ændr kodeord" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 #, fuzzy #| msgid "Shut Down Now" msgid "Shut down" msgstr "Sluk Nu" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Log ud" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 #, fuzzy #| msgid "Language" msgid "Select language" msgstr "Sprog" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Log ind" @@ -8687,6 +8653,39 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "Aktivér DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Akiver sikkerhedsudvidelser til DNS (DNSSEC)" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Firewall-tjenesten er ikke aktiv. Vær venlig at starte den. Den er som " +#~ "standard aktiveret på %(box_name)s. På Debian-baserede systemer (som " +#~ "%(box_name)s er) kan den startes med kommandoen 'service firewalld start' " +#~ "eller hvis systemet bruger systemd 'systemctl start firewalld'." + +#, fuzzy +#~| msgid "Mode" +#~ msgid "Migrate" +#~ msgstr "Tilstand" + +#, fuzzy +#~| msgid "Existing Backups" +#~ msgid "Error running apt-get" +#~ msgstr "Eksisterende sikkerhedskopier" + +#, fuzzy, python-format +#~| msgid "Plinth administrative interface for the %(box_name)s" +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Plinth administrationsværktøj til %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Netværksforbindelser" diff --git a/plinth/locale/de/LC_MESSAGES/django.po b/plinth/locale/de/LC_MESSAGES/django.po index 465475334..ba3bc854c 100644 --- a/plinth/locale/de/LC_MESSAGES/django.po +++ b/plinth/locale/de/LC_MESSAGES/django.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: FreedomBox UI\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: German calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1062,23 +1055,23 @@ msgstr "" "Nur Benutzer der calibre Gruppe können auf die App zugreifen. Alle " "Benutzer mit Zugangsberechtigung können alle Bibliotheken nutzen." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Verwenden von Calibre-E-Book-Bibliotheken" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-Book-Bibliothek" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Name der neuen Bibliothek" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1086,7 +1079,7 @@ msgstr "" "Nur Buchstaben des englischen Alphabets, Zahlen und die Zeichen _ . und - " "ohne Leerzeichen oder Sonderzeichen. Beispiel: Meine_Bibliothek_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Eine Bibliothek mit diesem Namen ist bereits vorhanden." @@ -1134,20 +1127,20 @@ msgstr "Gehe zur Bibliothek %(library)s" msgid "Delete library %(library)s" msgstr "Bibliothek löschen %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Bibliothek erstellt." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Beim Erstellen der Bibliothek ist ein Fehler aufgetreten." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} gelöscht." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "{name} konnte nicht gelöscht werden: {error}" @@ -1197,7 +1190,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Serververwaltung" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1205,18 +1198,18 @@ msgstr "" "Hier können Sie einige allgemeine Konfigurationsoptionen wie Hostname, " "Domainname, Webserver-Homepage usw. festlegen." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Allgemeine Konfiguration" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Konfigurieren" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1332,47 +1325,47 @@ msgstr "" "Die Protokolle enthalten Informationen darüber, wer auf das System " "zugegriffen hat, sowie Debug-Informationen von verschiedenen Diensten" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Fehler beim Setzen des Hostnamens: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Hostname gesetzt" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Fehler beim Setzen des Domainnamens: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Domainname gesetzt" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Fehler beim Setzen des Host-Namen: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Webserver-Startseite wurde definiert" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Fehler beim Ändern des erweiterten Modus: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Zeige erweiterte Anwendungen und Funktionen an" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Ausblenden von erweiterten Apps und Funktionen" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1385,7 +1378,7 @@ msgstr "" "verwenden, um eine Verbindung zwischen Parteien herzustellen, die sich sonst " "nicht miteinander verbinden können." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ejabberd müssen mit den hier angegebenen Details " "konfiguriert werden." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP-Helfer" @@ -1460,11 +1453,11 @@ msgstr "Fehler beim Setzen der Zeitzone: {exception}" msgid "Time zone set" msgstr "Zeitzone gesetzt" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge ist ein BitTorrent-Client mit einer Weboberfläche." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1472,16 +1465,16 @@ msgstr "" "Das Standardkennwort ist 'deluge'; Sie sollten sich aber anmelden und es " "sofort ändern, nachdem Sie diesen Dienst aktiviert haben." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Dateien mit BitTorrent herunterladen" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent-Webclient" @@ -1609,7 +1602,7 @@ msgstr "Ergebnis" msgid "Diagnostic Test" msgstr "Diagnose" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1621,7 +1614,7 @@ msgstr "" "zu finden. Dadurch werden andere daran gehindert, jene Dienste zu finden, " "die von Ihrer {box_name} angeboten werden." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1639,7 +1632,7 @@ msgstr "" "neuen IP zuweisen, und wenn jemand aus dem Internet nach Ihrem DNS-Namen " "fragt, erhält er eine Antwort mit Ihrer aktuellen IP-Adresse." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1652,11 +1645,11 @@ msgstr "" "freedns.afraid.org/\" target=\"_blank\">freedns.afraid.org können " "mittels Update-URL genutzt werden." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Dynamischer DNS-Client" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dynamischer Domain-Name" @@ -1787,7 +1780,7 @@ msgstr "Dieses Feld ist erforderlich." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1842,7 +1835,7 @@ msgstr "Server verweigert Verbindung" msgid "Already up-to-date" msgstr "Bereits auf dem neuesten Stand" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1850,7 +1843,7 @@ msgstr "" "XMPP ist ein offenes und standardisiertes Kommunikationsprotokoll. Hier " "können Sie Ihren XMPP-Server, genannt ejabberd, starten und konfigurieren." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client Benutzer mit " "einem {box_name} Login aufgerufen werden." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn-App oder konfiguriere einen externen " "Server." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Chatserver" @@ -2005,7 +1998,7 @@ msgstr "" "auf der Seite Systemeinstellungen " "konfigurieren." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -2016,7 +2009,7 @@ msgstr "" "Mail-Clients den Zugriff auf Ihre Mailbox über IMAP und POP3. Rspamd kümmert " "sich um Spam." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2029,7 +2022,7 @@ msgstr "" "ausdrücklichen Wunsch auf. Weitere Informationen finden Sie auf der " "Handbuchseite." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2044,7 +2037,7 @@ msgstr "" "Adresse Aliasnamen hinzufügen. Notwendige Aliase wie \"postmaster\" werden " "automatisch erstellt und verweisen auf den ersten Admin-Benutzer." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2052,7 +2045,7 @@ msgstr "" "Roundcube App bietet eine " "Weboberfläche für den Zugriff auf E-Mails." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2183,7 +2176,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "Host/Ziel/Wert" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2194,7 +2187,7 @@ msgstr "" "Verkehr Ihrer {box_name} kontrolliert. Die Firewall aktiv und korrekt " "konfiguriert halten reduziert Sicherheitsrisiken aus dem Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2214,52 +2207,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port -Name {name} ({details}) für externe Netzwerke nicht verfügbar" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Firewalldaemon läuft nicht. Bitte starten. Die Firewall ist standardmäßig " -"auf %(box_name)s aktiviert. Auf jedem Debian-basierten System (wie " -"%(box_name)s) kann sie über das Kommando „service firewalld start“ oder bei " -"einem System mit systemd mit „systemctl start firewalld“ gestartet werden." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Dienst/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Aktiviert" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Deaktiviert" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Erlaubt" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Erlaubt (nur intern)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Erlaubt (nur extern)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Geblockt" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2269,13 +2249,13 @@ msgstr "" "aktivieren, wird dieser in der Firewall ebenfalls aktiviert und wenn Sie " "einen Dienst deaktivieren, wird dieser ebenso in der Firewall deaktiviert." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Fortgeschritten" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2331,7 +2311,7 @@ msgstr "Einrichten beginnen" msgid "Setup Complete" msgstr "Installation abgeschlossen" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2350,7 +2330,7 @@ msgstr "" "Git-Befehlszeilenclient oder mit mehreren verfügbaren Grafikclients " "hochladen. Und Sie können Ihren Code mit Menschen auf der ganzen Welt teilen." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2358,71 +2338,71 @@ msgstr "" "Um weiter über Git Betrieb zu lernen, schauen Sie sich die Gitanleitung an." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Lese- und Schreibberechtigung auf Git respositories" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Einfaches Git Hosting" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Ungültige Repository-URL." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Ungültiger Respositoryname." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Name eines neuen Repositorys oder einer neuen URL zum Importieren eines " "vorhandenen Repositorys." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Beschreibung des Archivs" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Optional, zur Anzeige auf Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Name des Resposity Besitzers" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Privates Archiv" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Zugriff auf diesem Repository nur bevollmächtigte Benutzer erlauben." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Eine Archiv mit diesem Namen existiert bereits." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Name des resositorys" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" "Eine alphanumerische Zeichenfolge, die ein Repository eindeutig " "identifiziert." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Standard Thema" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb zeigt dies als Standard-Zweig an." @@ -2466,19 +2446,19 @@ msgstr "Git Repository %(name)s löschen" msgid "Delete this repository permanently?" msgstr "Dieses respository permanent löschen?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Archiv erstellt." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Beim Erstellen des Repository ist ein Fehler aufgetreten." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Archiv bearbeitet." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Archiv bearbeiten" @@ -2846,7 +2826,7 @@ msgstr "Über Ihre FreedomBox {box_name}" msgid "{box_name} Manual" msgstr "{box_name}-Handbuch" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2858,7 +2838,7 @@ msgstr "" "Anonymität, indem es verschlüsselten Datenverkehr über ein von Freiwilligen " "betriebenes, weltweit verteiltes Netzwerk sendet." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2866,7 +2846,7 @@ msgstr "" "Mehr Informationen über I2P finden Sie auf deren Projekt-Webseite." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2874,19 +2854,19 @@ msgstr "" "Der erste Besuch der bereitgestellten Weboberfläche leitet den " "Konfigurationsprozess ein." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "I2P-Anwendung verwalten" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Anonymisierungsnetzwerk" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2932,7 +2912,7 @@ msgstr "" "einem Peer-to-Peer-Netzwerk. Laden Sie Dateien herunter, indem Sie Torrents " "hinzufügen, oder erstellen Sie einen neuen Torrent, um eine Datei zu teilen." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2942,7 +2922,7 @@ msgstr "" "einfache Markup-Sprachen, einschließlich Markdown, und gängige Blogging-" "Funktionalität wie Kommentare und RSS-Feeds." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2956,15 +2936,15 @@ msgstr "" "\"{users_url}\">Benutzerkonfiguration können diese Rechte geändert oder " "neue Benutzer angelegt werden." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki und Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Wiki-Anwendungen ansehen und bearbeiten" @@ -3020,41 +3000,41 @@ msgstr "" "Diese Aktion wird alle Posts, Seiten und Kommentare einschließlich der " "Historie löschen. Dieses Wiki oder den Blog dauerhaft löschen?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Wiki {name} angelegt." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Wiki konnte nicht angelegt werden: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blog {name} angelegt." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Blog konnte nicht angelegt werden: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} gelöscht." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "{title} konnte nicht gelöscht werden: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted ist ein Server für Gobby, den kollaborativen Text-Editor." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3065,11 +3045,11 @@ msgstr "" "Client herunterladen und installieren. Dann Gobby starten und „Mit " "Server verbinden“ auswählen und den Domainnamen Ihrer {box_name} eingeben." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby-Server" @@ -3119,7 +3099,7 @@ msgstr "Janus-Videoraum" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "JavaScript-Lizenzinformation" @@ -3139,7 +3119,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Chatclient" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3155,7 +3135,7 @@ msgstr "" "Zertifizierungsstelle Let's Encrypt nachweist, der Inhaber einer Domain zu " "sein." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3169,15 +3149,15 @@ msgstr "" "akzeptieren Sie die Let's " "Encrypt Vetragsvereinbarungen vor der Verwendung dieses Dienstes." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Zertifikate" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Kann nicht testen: Es sind keine Domains konfiguriert." @@ -3242,7 +3222,7 @@ msgstr "" "Es wurden keine Domains konfiguriert. Um Zertifikate erhalten zu können, " "müssen Domains konfiguriert werden." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3251,34 +3231,34 @@ msgstr "" "Zertifikat erfolgreich widerrufen für Domain {domain}. Es kann einige " "Momente dauern, bis dies in Kraft tritt." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Fehler beim Widerrufen des Zertifikats für Domain {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Zertifikat erfolgreich bezogen für Domain {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Fehler beim Beziehen des Zertifikats für Domain {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Zertifikat erfolgreich widerrufen für Domain {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Fehler beim Widerrufen des Zertifikats für Domain {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3296,7 +3276,7 @@ msgstr "" "einem bestimmten Matrix Server können dank Föderation zwischen den Servern " "mit Nutzerkonten auf einem beliebigen anderen Server kommunizieren." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3306,7 +3286,7 @@ msgstr "" "Installiere die Coturn-App oder konfiguriere " "einen externen Server." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3414,7 +3394,7 @@ msgstr "" "Zertifikat. Bitte gehen Sie zu Let's " "Encrypt, um eines zu beziehen." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3427,7 +3407,7 @@ msgstr "" "nutzen, um eine Wiki-Webseite anzubieten, um Notizen zu schreiben oder um " "mit Freunden an einem Projekt zusammen zu arbeiten." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3442,7 +3422,7 @@ msgstr "" "Seite Spezial: Konto-" "Erstellen nutzen." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3450,12 +3430,12 @@ msgstr "" "Alle mit einem Link zu diesem Wiki können es lesen. Ausschließlich " "angemeldete Nutzer können den Inhalt verändern." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3540,35 +3520,35 @@ msgstr "" "Kennwortaktualisierung fehlgeschlagen. Bitte wählen Sie ein stärkeres " "Passwort" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Öffentliche Registrierung aktiviert" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Öffentliche Registrierung deaktiviert" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Privater Modus aktiviert" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Privater Modus ausgeschaltet" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Standard-Thema geändert" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Domainname aktualisiert" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Website-Name aktualisiert" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3581,11 +3561,11 @@ msgstr "" "Standardport (30000). Um auf dem Server zu spielen, wird ein Minetest-Client benötigt." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Block-Sandkasten" @@ -3638,7 +3618,7 @@ msgstr "" msgid "Address" msgstr "Adresse" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3826,7 +3806,7 @@ msgstr "Secure Shell" msgid "Services" msgstr "Dienste" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3835,7 +3815,7 @@ msgstr "" "eine Verbindung zum Internet her. Teilen Sie diese Verbindung mit anderen " "Geräten im Netzwerk." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3843,7 +3823,7 @@ msgstr "" "Geräte die mit anderen Methoden verwaltet werden, können hier möglicherweise " "nicht konfiguriert werden." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Netzwerke" @@ -4285,7 +4265,7 @@ msgstr "Verbindung bearbeiten" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Bearbeiten" @@ -4390,7 +4370,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Methode" @@ -4406,7 +4386,7 @@ msgstr "DNS-Server" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Standard" @@ -4419,7 +4399,7 @@ msgid "This connection is not active." msgstr "Diese Verbindung ist nicht aktiv." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Sicherheit" @@ -5012,7 +4992,7 @@ msgstr "Verbindung {name} gelöscht." msgid "Failed to delete connection: Connection not found." msgstr "Konnte Verbindung nicht löschen: Verbindung nicht gefunden." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -5029,20 +5009,20 @@ msgstr "" "{box_name} erlangen. Sie können auch auf das Internet via {box_name} für " "zusätzliche Sicherheit und Anonymität zugreifen." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Mit VPN-Diensten verbinden" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Virtuelles Privates Netzwerk" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5053,60 +5033,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" -"Migration zur ECC-Kryptographie (Kryptographie basierend auf elliptischen " -"Kurven)" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Ihre OpenVPN-Installation verwendet derzeit RSA. Der Umstieg auf die moderne " -"Elliptische-Kurven-Kryptographie verbessert die Geschwindigkeit des " -"Verbindungsaufbaus und die Sicherheit. Dieser Vorgang unumkehrbar. Sie " -"sollte auf den meisten Einplatinencomputern nur wenige Minuten dauern." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Alle neuen Installationen von OpenVPN auf %(box_name)s verwenden " -"standardmäßig ECC. Wir empfehlen, so bald wie möglich zu wechseln." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Warnung: Bestehende Client-Profile werden durch diese Operation " -"ungültig. Alle OpenVPN-Benutzer auf %(box_name)s müssen ihre neuen Profile " -"herunterladen. Für die Verbindung zu diesem Server sollten OpenVPN-Clients " -"verwendet werden, die mit ECC kompatibel sind." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migrieren" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Um eine Verbindung mit dem VPN von %(box_name)s herzustellen, müssen Sie ein " @@ -5115,18 +5056,19 @@ msgstr "" "verfügbar. Klicken Sie auf \"Mehr erfahren...\" empfohlenen Clients und " "Anweisungen zur Konfiguration." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Das Profil ist für jeden Benutzer von %(box_name)s spezifisch. Halten Sie es " "geheim." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Mein Profil herunterladen" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5139,19 +5081,19 @@ msgstr "" "die Dienste Ihrer {box_name} vom Internet nicht erreichbar sind. Dies " "umfasst folgende Situationen:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} ist hinter einer eingeschränkten Firewall." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} ist mit einem (wireless)-Router verbunden, den Sie nicht " "kontrollieren." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5159,7 +5101,7 @@ msgstr "" "Ihr ISP bietet Ihnen keine externe IP-Adresse, sondern statt dessen eine " "Internetverbindung über NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5167,11 +5109,11 @@ msgstr "" "Ihr ISP bietet keine statische IP-Adresse und Ihre IP-Adresse ändert sich " "immer, wenn Sie sich mit dem Internet verbinden." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Ihr ISP schränkt eingehende Verbindungen ein." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5185,23 +5127,23 @@ msgstr "" "\"https://pagekite.net\">pagekite.net. In der Zukunft könnte es möglich " "sein, hierfür die {box_name} eines Freundes zu nutzen." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Öffentliche Sichtbarkeit" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite Domäne" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Serverdomain" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5209,31 +5151,31 @@ msgstr "" "Wählen Sie Ihren PageKite-Server aus. „pagekite.net“ festlegen, um den " "Standardserver zu verwenden." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Serverport" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Port Ihres PageKite-Servers (standard: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite-Name" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Beispiel: meinebox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Ungültiger kite-Name" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite secret" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5241,35 +5183,35 @@ msgstr "" "Ein secret assoziiert mit dem kite oder das Standard-secret für Ihr Konto, " "wenn kein secret dem kite zugeordnet ist." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "Protokoll" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "externer (frontend) Port" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "interner (FreedomBox) Port" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Sub-Domainen einschalten" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Spezieller Dienst gelöscht" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Dieser Service ist bereits als Standard-Service verfügbar." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Spezieller Dienst hinzugefügt" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Dieser Dienst existiert bereits" @@ -5307,31 +5249,31 @@ msgstr "" "Beispielsweise HTTPS auf anderen Ports als 443, ist bekannt dafür, Probleme " "zu verursachen." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Webserver (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" "Webseite wird unter http://{0} verfügbar sein" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Webserver (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" "Webseite wird unter https://{0} verfügbar sein" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5383,8 +5325,8 @@ msgstr "" "Derzeit läuft eine Installation oder Update. Überlegen Sie auf die " "Fertigstellung zu warten, bevor Sie herunterfahren oder neu starten." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Neu starten" @@ -5435,6 +5377,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Jetzt herunterfahren" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5476,7 +5451,7 @@ msgstr "Web Proxy" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Zugang auf {url} über Proxy {proxy} auf TCP{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5494,7 +5469,7 @@ msgstr "" "mobilen App können verwendet werden, um sich mit ihm zu verbinden und oder " "zu trennen." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your Desktop und mobile Telefone zur Verfügung." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC-Client" @@ -5518,7 +5493,7 @@ msgstr "IRC-Client" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5533,7 +5508,7 @@ msgstr "" "supported-clients\">unterstützte Client Software notwendig. Radicale " "kann von jedem Benutzer mit einem {box_name}-Konto verwendet werden." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5544,12 +5519,12 @@ msgstr "" "Kontaktdaten wird nicht unterstützt; dies muss über einen separaten Client " "erfolgen." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Kalender und Adressbuch" @@ -5623,7 +5598,7 @@ msgstr "" "freedombox.adresse>) und ihren Benutzernamen. Wenn Sie auf den Suchen-Knopf " "drücken, werden die bestehenden Kalender und Adressbücher aufgelistet." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Konfiguration der Zugangsrechte aktualisiert" @@ -5718,7 +5693,7 @@ msgstr "" "Hinzufügen eines Feeds die Authentifizierung und verwenden Sie Ihre " "{box_name}-Anmeldeinformationen." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Lesen und Abonnieren von Neuigkeiten-Feeds" @@ -5731,7 +5706,7 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "RSS Feed Generator" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5739,7 +5714,7 @@ msgstr "" "Samba ermöglicht das Teilen von Dateien und Ordnern zwischen der FreedomBox " "und anderen Rechnern im lokalen Netzwerk." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5753,11 +5728,11 @@ msgstr "" "Windows) oder smb://{hostname}.local (unter Linux und Mac) zugegriffen " "werden. Es gibt drei Arten von Shares, aus denen Sie wählen können: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Offene Freigabe - für alle in Ihrem lokalen Netzwerk zugänglich." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5765,7 +5740,7 @@ msgstr "" "Gruppenfreigabe - nur für FreedomBox-Benutzer zugänglich, die sich in der " "Freedombox-Freigabegruppe befinden." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5773,15 +5748,15 @@ msgstr "" "Home Share - jeder Benutzer in der freedombox-share-Gruppe kann seinen " "eigenen privaten Raum haben." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Zugriff auf die privaten Freigaben" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Netzwerkdateispeicherung" @@ -5869,15 +5844,15 @@ msgstr "Freigabename" msgid "Action" msgstr "Aktion" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS Datenträger" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Open Share" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Group Share" @@ -5903,7 +5878,7 @@ msgstr "Freigabe deaktiviert." msgid "Error disabling share: {error_message}" msgstr "Fehler beim Deaktivieren der Freigabe: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5911,7 +5886,7 @@ msgstr "" "Searx ist eine Internet-Metasuchmaschine, die die Privatsphäre respektiert. " "Sie sammelt und zeigt Ergebnisse von mehreren Suchmaschinen an." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5919,41 +5894,41 @@ msgstr "" "Searx kann verwendet werden, um Nachverfolgung und Profiling durch " "Suchmaschinen zu vermeiden. Standardmäßig werden keine Cookies gespeichert." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Suche im Web" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Websuche" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Sichere Suche" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Wählen Sie den standardmäßigen Familienfilter, der auf Ihre Suchergebnisse " "angewendet werden soll." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Moderat" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Streng" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Öffentlichen Zugang erlauben" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Erlauben, dass diese Anwendung von jedem verwendet werden kann, der sie " @@ -6135,7 +6110,7 @@ msgstr "Lesezeichen" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6145,7 +6120,7 @@ msgstr "" "Internetverkehr zu schützen. Er kann verwendet werden, um Internetfilterung " "und -zensur zu umgehen." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6158,7 +6133,7 @@ msgstr "" "betrieben. Lokale Geräte können sich mit diesem Proxy verbinden, und deren " "Daten werden verschlüsselt über den Shadowsocks-Server weitergeleitet." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6167,44 +6142,44 @@ msgstr "" "SOCKS5-Proxy in ihrem Gerät, Browser, oder Anwendung auf http://" "Freedombox_Adresse:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Socks5-Proxy" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Empfohlen" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Server" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Servername oder IP-Adresse" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Server-Portnummer" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Passwort, um Daten zu verschlüsseln. Muss mit dem Server-Passwort " "übereinstimmen." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" "Verschlüsselungsverfahren. Muss mit der Einstellung des Servers " "übereinstimmen." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6213,15 +6188,15 @@ msgstr "" "Sharing ermöglicht es Ihnen, Dateien und Ordner auf Ihrer {box_name} über " "das Internet mit ausgewählten Benutzergruppen zu teilen." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Sharing" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Name der Freigabe" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6229,30 +6204,30 @@ msgstr "" "Eine alphanumerische Zeichenfolge in Kleinbuchstaben, die eine Freigabe " "eindeutig identifiziert. Beispiel: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Freizugebender Pfad" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" "Plattenpfad zu einem Ordner auf diesem Server, den Sie freigeben möchten." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Öffentlich freigeben" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" "Dateien in diesem Ordner jedem zur Verfügung stellen, der über den Link " "verfügt." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Benutzergruppen, die Dateien in der Freigabe lesen können:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6260,11 +6235,11 @@ msgstr "" "Benutzer der ausgewählten Benutzergruppen können die Dateien in der Freigabe " "lesen." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Eine Freigabe mit diesem Namen existiert bereits." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Freigaben sollten öffentlich sein oder mindestens einer Gruppe haben" @@ -6301,19 +6276,19 @@ msgstr "Freigabe hinzugefügt." msgid "Add Share" msgstr "Freigabe hinzufügen" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Freigabe geändert." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Freigabe bearbeiten" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Freigabe gelöscht." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6324,7 +6299,7 @@ msgstr "" "unerwünschte Änderungen in einen vorherigen bekannten guten Zustand zurück " "zu versetzen." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6336,7 +6311,7 @@ msgstr "" "Software. Ältere Schnappschüsse werden gemäß den Einstellungen unten " "automatisch bereinigt." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for Datensicherungen, da sie nur auf derselben " "Partition gespeichert werden können. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Speicherauszüge" @@ -6451,7 +6426,7 @@ msgstr "Datum" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Speicherauszüge löschen" @@ -6505,60 +6480,60 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Zurücksetzen auf Speicherauszug #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "Manuell erstellt" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "Zeitleiste" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Schnappschüsse verwalten" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Schnappschuss erstellt." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Konfiguration der Speicherauszüge aktualisiert" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Aktionsfehler: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Ausgewählte Schnappschüsse gelöscht" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" "Schnappschüsse ist derzeit im Gebrauch. Bitte versuchen Sie es später noch " "einmal." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Zurückgesetzt auf Speicherauszug #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" "Das System muss neu gestartet werden, um das Zurücksetzen abzuschließen." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Zurücksetzen auf Speicherauszug" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6570,7 +6545,7 @@ msgstr "" "verifizierter, entfernter Computer Verwaltungsaufgaben ausführen, Dateien " "kopieren oder andere Anwendungen starten." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Secure Shell (SSH) Server" @@ -6609,14 +6584,6 @@ msgstr "Algorithmus" msgid "Fingerprint" msgstr "Fingerabdruck" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "SSH-Authentifizierung mit Passwort deaktiviert." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "SSH-Authentifizierung mit Passwort aktiviert." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Einmal-Anmeldung" @@ -6629,7 +6596,7 @@ msgstr "Anmelden" msgid "Logged out successfully." msgstr "Erfolgreich abgemeldet." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6641,109 +6608,109 @@ msgstr "" "Speichermedien einsehen, Wechselmedien einbinden und aushängen, die Root-" "Partition erweitern usw." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Speicher" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} Bytes" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Der Vorgang schlug fehl." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Der Vorgang wurde abgebrochen." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Das Gerät wird bereits ausgehängt." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "Der Vorgang ist wegen fehlender Treiber-/Werkzeugunterstützung nicht möglich." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Der Vorgang beendet wegen Zeitüberschreitung." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" "Dieser Vorgang würde ein Gerät aufwecken, welches sich in einem Tiefschlaf-" "Zustand befindet." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Es wird versucht, ein Gerät auszuhängen, das beschäftigt ist." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Dieser Vorgang wurde bereits abgebrochen." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Nicht autorisiert, um den gewünschten Vorgang auszuführen." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Dieses Gerät ist bereits eingebunden." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Das Gerät ist nicht eingebunden." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Die gewünschte Option ist nicht gestattet." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Das Gerät ist von einem anderen Benutzer eingebunden." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Geringer Speicherplatz auf der Systempartition: {percent_used}% belegt, " "{free_space} verfügbar." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Wenig Plattenspeicherplatz" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Festplattenfehler unmittelbar bevorstehend" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6753,39 +6720,39 @@ msgstr "" "Kopieren Sie alle Daten, solange Sie noch können, und ersetzen Sie das " "Laufwerk." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Ungültiger Verzeichnisname." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Verzeichnis ist nicht vorhanden." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Pfad ist kein Verzeichnis." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Verzeichnis ist für den Benutzer nicht lesbar." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Das Verzeichnis ist für den Benutzer nicht beschreibbar." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Verzeichnis" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Unterverzeichnis (optional)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Freigeben" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Anderes Verzeichnis (unten angeben)" @@ -6823,7 +6790,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Erweitern der Root-Partition" @@ -6847,30 +6814,30 @@ msgstr "" "Nach dieser Aktion werden %(expandable_root_size)s zusätzlicher " "Speicherplatz auf der Root-Partition verfügbar." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Fehler beim Erweitern des Dateisystems: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Partition erfolgreich vergrößert." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} kann sicher entfernt werden." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Gerät kann sicher entfernt werden." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Fehler beim Auswerfen des Geräts: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6882,7 +6849,7 @@ msgstr "" "Modifikation oder Löschen von Dateien auf einem Gerät wird automatisch auf " "allen anderen Geräten reproduziert, auf denen Syncthing läuft." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6902,20 +6869,20 @@ msgstr "" "{box_name} ist nur für Benutzer der \"Admin\" oder \"Syncthing-access\"-" "Gruppe zugänglich." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Syncthing-Anwendung einstellen" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Dateisynchronisation" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6929,7 +6896,7 @@ msgstr "" "Sie den Tor Browser verwenden." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6938,40 +6905,40 @@ msgstr "" "Tor SOCKS-Port ist auf Ihrer {box_name} für interne Netzwerke auf TCP port " "9050 verfügbar." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor-Onion-Dienste" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor-Socks-Proxy" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor-Bridge-Relay" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor-Relay-Port ist verfügbar" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3-Transport registriert" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4-Transport registriert" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Zugangs-URL {url} auf TCP{kind} über Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Tor-Nutzung auf {url} über TCP{kind} bestätigen" @@ -7094,11 +7061,11 @@ msgstr "Onion-Dienste" msgid "Ports" msgstr "Ports" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Aktualisieren der Konfiguration" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Fehler beim Konfigurieren der App: {error}" @@ -7160,7 +7127,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7169,7 +7136,7 @@ msgstr "" "Tiny Tiny RSS ist ein Feedreader (RSS/Atom), der von jedem Browser aus " "genutzt werden kann, sich aber sehr wie eine normale Anwendung anfühlt." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7178,7 +7145,7 @@ msgstr "" "Wenn aktiviert, kann Tiny Tiny RSS von jedem " "Benutzer der zur Feed-Reader-Gruppe gehört, aufgerufen werden." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7187,11 +7154,11 @@ msgstr "" "verwenden Sie die URL /tt-rss-app für die " "Verbindung." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Feedreader" @@ -7199,14 +7166,14 @@ msgstr "Feedreader" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Suchen Sie nach den neuesten Software- und Sicherheitsupdates und " "installieren Sie diese." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7220,22 +7187,22 @@ msgstr "" "erachtet wird, erfolgt dieser automatisch um 02:00 Uhr, so dass alle Apps " "kurzzeitig nicht verfügbar sind." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Software-Aktualisierung" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox aktualisiert" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Distributions-Update konnte nicht gestartet werden" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7246,11 +7213,11 @@ msgstr "" "mindestens 5 GB frei sind. Das Distributions-Update wird nach 24 Stunden " "erneut versucht, falls aktiviert." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Distributions-Upgrade gestartet" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7430,44 +7397,44 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Distributions-Upgrade jetzt testen" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Fehler beim Konfigurieren von automatischen Aktualisierungen: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatische Systemaktualisierung aktivieren" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatische Aktualisierungen ausgeschaltet" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Distributions-Upgrade aktiviert" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Distributions-Upgrade deaktiviert" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Aktualisierung gestartet." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Starten der Aktualisierung fehlgeschlagen." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Häufige Funktions-Updates aktiviert." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Starten des Verteilungsupgradetests." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7478,7 +7445,7 @@ msgstr "" "muss ein Benutzerkonto Teil einer Gruppe sein, damit ein Benutzer auf die " "App zugreifen kann." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7490,15 +7457,15 @@ msgstr "" "dürfen nur Mitglieder der Gruppe admin Apps oder " "Systemeinstellungen ändern." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Benutzer und Gruppen" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Zugriff auf alle Anwendungen und Systemeinstellungen" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "LDAP-Eintrag „{search_item}“ prüfen" @@ -7518,11 +7485,11 @@ msgstr "" "Erforderlich. Bis zu 150 Zeichen. Nur englische Buchstaben, Ziffern und " "@/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Autorisierungs-Passwort" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7530,11 +7497,11 @@ msgstr "" "Geben Sie das Passwort für den Benutzer „{user}“ ein, um Kontoänderungen zu " "autorisieren." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Ungültiges Passwort." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7549,12 +7516,12 @@ msgstr "" "allen Diensten anmelden und sie können sich auch über SSH im System anmelden " "und besitzen Administratorrechte (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Erstellen des LDAP-Benutzers ist fehlgeschlagen:{error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -7575,42 +7542,42 @@ msgstr "" "eingeben, einen pro Zeile. Leerzeilen und Zeilen, die mit # beginnen, werden " "ignoriert." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Umbenennen des LDAP-Benutzers fehlgeschlagen." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Entfernen des Benutzers von der Gruppe fehlgeschlagen." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Hinzufügen eines Benutzers zur Gruppe ist fehlgeschlagen." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "SSH-Schlüssel kann nicht gesetzt werden." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Fehler beim Ändern des Benutzerstatus." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Ändern des LDAP-Benutzerpassworts ist fehlgeschlagen." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" "Fehler beim Hinzufügen eines neuen Benutzers zur Administratorgruppe: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Fehler beim Einschränken des Konsolenzugriffs: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Benutzerkonto wurde erstellt, Sie sind jetzt angemeldet" @@ -7627,12 +7594,12 @@ msgstr "Passwort speichern" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Benutzer anlegen" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Benutzer löschen" @@ -7673,13 +7640,19 @@ msgid "The following administrator accounts exist in the system." msgstr "Die folgenden Administratorkonten sind im System vorhanden." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Löschen Sie diese Konten von der Befehlszeile aus und aktualisieren Sie die " "Seite, um ein Konto zu erstellen, das mit %(box_name)s verwendet werden " @@ -7689,7 +7662,7 @@ msgstr "" "Schritt." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Benutzer" @@ -7723,34 +7696,34 @@ msgstr "" msgid "Save Changes" msgstr "Änderungen speichern" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Benutzer %(username)s angelegt." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Benutzer %(username)s geändert." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Benutzer bearbeiten" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Benutzer {user} gelöscht." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Löschen von LDAP-Benutzer fehlgeschlagen." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Passwort ändern" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Passwort erfolgreich geändert." @@ -8095,7 +8068,7 @@ msgstr "Verbindung zum Server löschen" msgid "Server deleted." msgstr "Server gelöscht." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8110,7 +8083,7 @@ msgstr "" "Verwaltungsoberfläche und die erstellten Webseiten sind für mobile Geräte " "geeignet." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8124,7 +8097,7 @@ msgstr "" "zugreifen. Aktivieren Sie Permalinks in der Administratoroberfläche, um " "bessere URLs für Ihre Seiten und Beiträge zu erhalten." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8135,7 +8108,7 @@ msgstr "" "wordpress/wp-admin/\">Administrationsseite, um die " "Administrationsoberfläche in Zukunft zu erreichen." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8146,12 +8119,12 @@ msgstr "" "Plugins oder Themes können auf Ihr eigenes Risiko installiert und " "aktualisiert werden." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Internetseite und Blog" @@ -8168,7 +8141,7 @@ msgstr "" "Administratoren die WordPress-Website oder den Blog aufrufen. Aktivieren Sie " "diese Option erst nach der Ersteinrichtung von WordPress." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8193,7 +8166,7 @@ msgstr "" "Einzelne Fotos können mit anderen geteilt werden, indem ein direkter Link " "gesendet wird." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8204,11 +8177,11 @@ msgstr "" "Administrator in Zoph. Für zusätzliche Benutzer müssen Konten sowohl in " "{box_name} als auch in Zoph mit demselben Benutzernamen erstellt werden." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Foto-Manager" @@ -8262,96 +8235,92 @@ msgstr "Warten auf den Start: {name}" msgid "Finished: {name}" msgstr "Fertig: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Paket {expression} ist nicht verfügbar" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Paket {package_name} ist die aktuellste Version ({latest_version})" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "Fehler beim Ausführen von apt-get" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "Installation läuft" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "herunterladen" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "Medienwechsel" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "Konfigurationsdatei: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Zeitüberschreitung beim Warten auf den Paket-Manager" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Installation der App" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Aktualisieren der App" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Fehler bei der Installation der App: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Fehler beim Aktualisieren der App: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Fehler bei der Installation der App: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Fehler beim Aktualisieren der App: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "App installiert." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "App aktualisiert" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Deinstallation der App" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Fehler bei der Deinstallation der App: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Fehler bei der Deinstallation der App: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "App deinstalliert." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Aktualisieren von App-Paketen" @@ -8413,53 +8382,54 @@ msgstr "Installation" msgid "Service %(service_name)s is not running." msgstr "Dienst %(service_name)s läuft nicht." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Kernfunktionalität und Weboberfläche für %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Startseite" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Startseite" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Apps" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Apps" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " System" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "System" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Passwort ändern" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Herunterfahren" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Abmelden" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Sprache wählen" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Anmelden" @@ -8749,6 +8719,77 @@ msgstr "vor der Deinstallation von {app_id}" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "DNSSEC einschalten" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Domain-Name-System-Sicherheitserweiterungen (DNSSEC) aktivieren" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Firewalldaemon läuft nicht. Bitte starten. Die Firewall ist standardmäßig " +#~ "auf %(box_name)s aktiviert. Auf jedem Debian-basierten System (wie " +#~ "%(box_name)s) kann sie über das Kommando „service firewalld start“ oder " +#~ "bei einem System mit systemd mit „systemctl start firewalld“ gestartet " +#~ "werden." + +#~ msgid "Migrate to ECC" +#~ msgstr "" +#~ "Migration zur ECC-Kryptographie (Kryptographie basierend auf elliptischen " +#~ "Kurven)" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Ihre OpenVPN-Installation verwendet derzeit RSA. Der Umstieg auf die " +#~ "moderne Elliptische-Kurven-Kryptographie verbessert die Geschwindigkeit " +#~ "des Verbindungsaufbaus und die Sicherheit. Dieser Vorgang unumkehrbar. " +#~ "Sie sollte auf den meisten Einplatinencomputern nur wenige Minuten dauern." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Alle neuen Installationen von OpenVPN auf %(box_name)s verwenden " +#~ "standardmäßig ECC. Wir empfehlen, so bald wie möglich zu wechseln." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Warnung: Bestehende Client-Profile werden durch diese Operation " +#~ "ungültig. Alle OpenVPN-Benutzer auf %(box_name)s müssen ihre neuen " +#~ "Profile herunterladen. Für die Verbindung zu diesem Server sollten " +#~ "OpenVPN-Clients verwendet werden, die mit ECC kompatibel sind." + +#~ msgid "Migrate" +#~ msgstr "Migrieren" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "SSH-Authentifizierung mit Passwort deaktiviert." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "SSH-Authentifizierung mit Passwort aktiviert." + +#~ msgid "Error running apt-get" +#~ msgstr "Fehler beim Ausführen von apt-get" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Kernfunktionalität und Weboberfläche für %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Netzwerkverbindungen" diff --git a/plinth/locale/django.pot b/plinth/locale/django.pot index 154274480..1efa403c4 100644 --- a/plinth/locale/django.pot +++ b/plinth/locale/django.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -109,17 +109,17 @@ msgstr "" msgid "{box_name} Web Interface (Plinth)" msgstr "" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -130,48 +130,48 @@ msgid "" "network." msgstr "" -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "" -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." msgstr "" -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " "succeed. The latest error is: {error_message}" msgstr "" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "" @@ -303,7 +303,7 @@ msgstr "" msgid "Key in Repository" msgstr "" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "" @@ -367,37 +367,37 @@ msgstr "" msgid "Select verified SSH public key" msgstr "" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." msgstr "" -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "" -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "" @@ -452,7 +452,7 @@ msgid "Create Location" msgstr "" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "" @@ -675,7 +675,7 @@ msgstr "" msgid "Mounting failed" msgstr "" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -683,7 +683,7 @@ msgid "" "can be set to expire after a time period." msgstr "" -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -691,7 +691,7 @@ msgid "" "permissions." msgstr "" -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -699,39 +699,39 @@ msgid "" "the list." msgstr "" -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "" @@ -745,7 +745,7 @@ msgstr "" #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "" @@ -778,35 +778,35 @@ msgstr "" #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -818,41 +818,41 @@ msgstr "" msgid "Delete" msgstr "" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "" -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "" -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "" -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "" -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." msgstr "" -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -860,31 +860,23 @@ msgid "" "connection from {box_name}." msgstr "" -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "" @@ -916,19 +908,20 @@ msgstr "" msgid "Refresh IP address and domains" msgstr "" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -936,7 +929,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -945,35 +938,35 @@ msgid "" "highlighted text. Content distribution using OPDS is currently not supported." msgstr "" -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1019,20 +1012,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1070,24 +1063,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1183,47 +1176,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1231,7 +1224,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1461,11 +1454,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1577,7 +1570,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1632,13 +1625,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1760,14 +1753,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1775,7 +1768,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1785,13 +1778,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1916,7 +1909,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1924,7 +1917,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1944,61 +1937,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2044,7 +2028,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2055,73 +2039,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2165,19 +2149,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2470,7 +2454,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2478,31 +2462,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2539,14 +2523,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2555,15 +2539,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2617,41 +2601,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2659,11 +2643,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2709,7 +2693,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2727,7 +2711,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2737,7 +2721,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2745,15 +2729,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2816,41 +2800,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2860,14 +2844,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2948,7 +2932,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2956,7 +2940,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2965,18 +2949,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3045,35 +3029,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3082,11 +3066,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3131,7 +3115,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3290,19 +3274,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3648,7 +3632,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3753,7 +3737,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3769,7 +3753,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3782,7 +3766,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4318,7 +4302,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4329,20 +4313,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4352,61 +4336,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4415,33 +4367,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4450,87 +4402,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4564,29 +4516,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4628,8 +4580,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4671,6 +4623,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4702,7 +4685,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4713,7 +4696,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4733,7 +4716,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4743,19 +4726,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4814,7 +4797,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4881,7 +4864,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4894,13 +4877,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4909,31 +4892,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5011,15 +4994,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5045,51 +5028,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5242,14 +5225,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5258,97 +5241,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5385,26 +5368,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5412,14 +5395,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5513,7 +5496,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5561,57 +5544,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5619,7 +5602,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5652,14 +5635,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5672,7 +5647,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5680,143 +5655,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5850,7 +5825,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5868,30 +5843,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5899,7 +5874,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5911,20 +5886,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5933,47 +5908,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6071,11 +6046,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6127,31 +6102,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6159,12 +6134,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6172,33 +6147,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6346,51 +6321,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6398,15 +6373,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6424,21 +6399,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6447,12 +6422,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6468,41 +6443,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6519,12 +6494,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6562,17 +6537,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6603,34 +6578,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6939,7 +6914,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6948,7 +6923,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6957,26 +6932,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6990,7 +6965,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7003,7 +6978,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7011,11 +6986,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7064,96 +7039,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7204,53 +7175,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/el/LC_MESSAGES/django.po b/plinth/locale/el/LC_MESSAGES/django.po index 224513bbf..2a9d3eced 100644 --- a/plinth/locale/el/LC_MESSAGES/django.po +++ b/plinth/locale/el/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:20+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Greek calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Name of the repository" msgid "Name of the new library" msgstr "Όνομα του αποθετηρίου" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 #, fuzzy #| msgid "A share with this name already exists." msgid "A library with this name already exists." @@ -1157,24 +1149,24 @@ msgstr "" msgid "Delete library %(library)s" msgstr "Διαγραφή ιστότοπου %(site)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "Repository created." msgid "Library created." msgstr "Το αποθετήριο δημιουργήθηκε." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 #, fuzzy #| msgid "An error occurred while creating the repository." msgid "An error occurred while creating the library." msgstr "Παρουσιάστηκε σφάλμα κατά τη δημιουργία του αποθετηρίου." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "το {name} διαγράφηκε." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Δεν ήταν δυνατή η διαγραφή του {name}: {error}" @@ -1219,7 +1211,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Διαχείριση διακομιστή" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1228,18 +1220,18 @@ msgstr "" "υπολογιστή, το όνομα διαδικτύου σας, την κεντρική ιστοσελίδα του διακομιστή " "διαδικτύου κλπ." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Γενικές ρυθμίσεις" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Ρυθμίσετε" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1354,49 +1346,49 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Σφάλμα κατά τη ρύθμιση του ονόματος του υπολογιστή: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "To όνομα του υπολογιστη ρυθμίστηκε επιτυχώς" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Σφάλμα κατά τη ρύθμιση ονόματος διδαδικτύου: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "To όνομα διαδικτύου ρυθμίστηκε επιτυχώς" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" "Σφάλμα κατά τη ρύθμιση της αρχικής σελίδας διακομιστή διαδικτύου: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Aρχική σελίδα διακομιστή διαδικτύου ρυθμίστηκε" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" "Παρουσιάστηκε σφάλμα κατά την αλλαγή σε προηγμένη λειτουργία: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Εμφανίζονται προηγμένες εφαρμογές και λειτουργίες" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Απόκρυψη προηγμένων εφαρμογών και χαρακτηριστικών" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1404,7 +1396,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as freedns." "afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Πελάτης δυναμικού DNS" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Δυναμικό όνομα διαδικτύου" @@ -1825,7 +1817,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1894,7 +1886,7 @@ msgstr "Διαγραφή σύνδεσης" msgid "Already up-to-date" msgstr "Ενεργοποίηση αυτόματων ενημερώσεων" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1903,7 +1895,7 @@ msgstr "" "μπορείτε να εκτελέσετε και να ρυθμίσετε τις παραμέτρους του διακομιστή XMPP, " "που ονομάζεται ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientπιστοποιητικά για το {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Διακομιστής συνομιλίας" @@ -2050,14 +2042,14 @@ msgstr "" "%(domainname)s. Μπορείτε να ρυθμίσετε το όνομα της υπηρεσίας στο Ρυθμίστε page." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2065,7 +2057,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2075,13 +2067,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2224,7 +2216,7 @@ msgstr "Θύρα" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2236,7 +2228,7 @@ msgstr "" "προστασίας ενεργοποιημένο και η σωστή ρύθμιση παραμέτρων μειώνει τον κίνδυνο " "απειλών προερχόμενων από το Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall (τείχος προστασίας)" @@ -2256,54 +2248,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Η θύρα {name} ({details}) δεν είναι διαθέσιμη για εξωτερικά δίκτυα" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"To πρόγραμμα τείχους προστασίας δεν εκτελείται. Παρακαλείστε να το τρέξετε. " -"Το τείχος προστασίας εμφανίζεται ενεργοποιημένο από προεπιλογή στο " -"%(box_name)s. Σε οποιοδήποτε σύστημα που βασίζεται στο Debian (όπως το " -"%(box_name)s) μπορείτε να το εκτελέσετε χρησιμοποιώντας την εντολή ' service " -"firewalld start ' ή σε περίπτωση ενός συστήματος με systemd ' systemctl " -"start firewalld '." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Υπηρεσία/θύρα" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Ενεργοποιήθηκε" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Απενεργοποιήθηκε" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Επιτρέπεται" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Επιτρέπεται (μόνο εσωτερικά)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Επιτρέπεται (εξωτερικά μόνο)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Αποκλείστηκε" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2313,13 +2290,13 @@ msgstr "" "υπηρεσία, επιτρέπεται επίσης στο τείχος προστασίας και όταν απενεργοποιείτε " "μια υπηρεσία είναι επίσης απενεργοποιημένη στο τείχος προστασίας." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Για προχωρημένους" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2370,7 +2347,7 @@ msgstr "Έναρξη εγκατάστασης" msgid "Setup Complete" msgstr "Η εγκατάσταση ολοκληρώθηκε" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2389,7 +2366,7 @@ msgstr "" "πολλαπλές διαθέσιμες γραφικές εφαρμογές-πελάτες. Και μπορείτε να μοιραστείτε " "τον κώδικά σας με τους ανθρώπους σε όλο τον κόσμο." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2397,75 +2374,75 @@ msgstr "" "Για να μάθετε περισσότερα για το git μάθημα git." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Πρόσβαση ανάγνωσης και εγγραφής σε αποθετήρια Git" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Απλό Hosting Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Μη έγκυρη διεύθυνση URL για το αποθετήριο." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Μη έγκυρο όνομα αποθετηρίου." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Όνομα νέου αποθετηρίου ή διεύθυνσης URL για την εισαγωγή υπάρχοντος " "αποθετηρίου." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Περιγραφή του αποθετηρίου" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Προαιρετικά, για την εμφάνιση στην Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Όνομα κατόχου αποθετηρίου" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Ιδιωτικό αποθετήριο" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" "Να επιτρέπεται μόνο σε εξουσιοδοτημένους χρήστες η πρόσβαση σε αυτό το " "αποθετήριο." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Υπάρχει ήδη ένα αποθετήριο με αυτό το όνομα." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Όνομα του αποθετηρίου" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" "Μια αλφαριθμητική συμβολοσειρά που προσδιορίζει με μοναδικό τρόπο ένα " "αποθετήριο." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default Skin" msgid "Default branch" msgstr "Προεπιλεγμένη εμφάνιση" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2511,19 +2488,19 @@ msgstr "Διαγραφή αποθετηρίου Git %(name)s" msgid "Delete this repository permanently?" msgstr "Να διαγραφεί μόνιμα αυτό το αποθετήριο;" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Το αποθετήριο δημιουργήθηκε." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Παρουσιάστηκε σφάλμα κατά τη δημιουργία του αποθετηρίου." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "To αποθετήριο τροποποιήθηκε." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Τροποποίηση αποθετηρίου" @@ -2906,7 +2883,7 @@ msgstr "Σχετικά με το {box_name}" msgid "{box_name} Manual" msgstr "Εγχειρίδιο για το {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2918,7 +2895,7 @@ msgstr "" "παρακολούθηση. Το i2p παρέχει ανωνυμία κατά την αποστολή κρυπτογραφημένης " "κυκλοφορίας μέσα από ένα εθελοντικό δίκτυο διανεμημένο σε όλο τον κόσμο." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2926,7 +2903,7 @@ msgstr "" "Βρείτε περισσότερες πληροφορίες σχετικά με το έργο τους Ι2Ρ." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2934,19 +2911,19 @@ msgstr "" "Η πρώτη επίσκεψη στο παρεχόμενο δικτυακό περιβάλλον θα ξεκινήσει τη " "διαδικασία ρύθμισης." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Διαχείριση εφαρμογής I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Δίκτυο ανωνυμίας" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "Διακομιστής μεσολάβησης I2P" @@ -2997,7 +2974,7 @@ msgstr "" "to-peer δίκτυο. Κατεβάστε τα αρχεία με την προσθήκη torrents ή δημιουργήστε " "ένα νέο torrent για να μοιραστείτε ένα αρχείο." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -3007,7 +2984,7 @@ msgstr "" "ελαφριές γλώσσες σήμανσης, όπως Markdown και κοινές λειτουργίες ιστολογίου, " "όπως σχόλια και τροφοδοσίες RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -3022,15 +2999,15 @@ msgstr "" "\"{users_url}\">ρυθμίσεις μπορεί να γίνει ρύθμιση παραμέτρων χρήστη και " "να αλλάξετε τα δικαιώματα ή να προσθέσετε νέους χρήστες." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki και Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Προβολή και επεξεργασία εφαρμογών wiki" @@ -3087,43 +3064,43 @@ msgstr "" "σχόλια, συμπεριλαμβανομένου του ιστορικού αναθεωρήσεων. Να διαγραφεί " "οριστικά αυτό το wiki ή το blog;" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Δημιουργήθηκε το wiki {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Δεν ήταν δυνατή η δημιουργία wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Δημιουργήθηκε το blog {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Δεν ήταν δυνατή η δημιουργία ιστολογίου: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} διαγράφηκε." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Δεν ήταν δυνατή η διαγραφή του {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" "infinoted είναι ένας διακομιστής για Γκόμπι, ένα πρόγραμμα που μπορείτε να " "συνεργαστείτε στην επεξεργασία κειμένου." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3135,11 +3112,11 @@ msgstr "" "επιλέξτε \"σύνδεση στο διακομιστή\" και πληκτρολογήστε το όνομα διαδικτύου " "σας για το {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby Server" @@ -3187,7 +3164,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Πληροφορίες άδειας χρήσης JavaScript" @@ -3207,7 +3184,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Πρόγραμμα-πελάτης συνομιλίας" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3223,7 +3200,7 @@ msgstr "" "αποδεικνύοντας ότι είναι ο ιδιοκτήτης ενός ονόματος στην υπηρεσία Let's " "Encrypt, μια αρχή έκδοσης πιστοποιητικών (CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3237,15 +3214,15 @@ msgstr "" "letsencrypt.org/repository/\">Συμφωνία Συνδρομητή Lets Encrypt πριν από " "τη χρήση αυτής της υπηρεσίας." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Πιστοποιητικά" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3310,7 +3287,7 @@ msgstr "" "Δεν έχουν ρυθμιστεί ονόματα διαδικτύου Ρυθμίσετε " "όνομα διαδικτύου για να μπορείτε να αποκτήσετε πιστοποιητικά για αυτό." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3319,34 +3296,34 @@ msgstr "" "Το πιστοποιητικό ακυρώθηκε με επιτυχία για τον όνομα {domain}. Αυτό μπορεί " "να διαρκέσει λίγα λεπτά για να τεθεί σε ισχύ." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Απέτυχε η ανάκληση του πιστοποιητικού για το όνομα {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Το πιστοποιητικό αποκτήθηκε με επιτυχία για το όνομα {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Αποτυχία λήψης πιστοποιητικού για το όνομα {domain} {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Το πιστοποιητικό διαγράφηκε επιτυχώς για το όνομα {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Αποτυχία διαγραφής πιστοποιητικού για το όνομα {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3364,14 +3341,14 @@ msgstr "" "να συνομιλήσουν με τους χρήστες σε όλες τις άλλες διακομιστές Matrix μέσω " "ομοσπονδίας." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3479,7 +3456,7 @@ msgstr "" "TLS πιστοποιητικό. Μεταβείτε στη διεύθυνση " "Lets Encrypt για να αποκτήσετε ένα." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3492,7 +3469,7 @@ msgstr "" "χρησιμοποιήσετε το wiki για να φιλοξενήσετε μια ιστοσελίδα που μοιάζει με " "wiki, να πάρετε σημειώσεις ή να συνεργαστείτε με φίλους σε έργα." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3507,7 +3484,7 @@ msgstr "" "λογαριασμούς χρηστών από το ίδιο το wiki, πηγαίνοντας στη σελίδα Δημιουργία λογαριασμού." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3515,12 +3492,12 @@ msgstr "" "Όποιος έχει μια διεύθυνση URL για αυτό το wiki μπορεί να το διαβάσει. Μόνο " "οι χρήστες που είναι συνδεδεμένοι μπορούν να κάνουν αλλαγές στο περιεχόμενο." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "Mediawiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3609,39 +3586,39 @@ msgstr "" "Κωδικός πρόσβασης που χρησιμοποιείται για την κρυπτογράφηση δεδομένων. " "Πρέπει να ταιριάζει με τον κωδικό πρόσβασης του διακομιστή." -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Η δημόσια εγγραφή ενεργοποιήθηκε" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Οι δημόσιες εγγραφές είναι απενεργοποιημένες" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Η ιδιωτική λειτουργία είναι ενεργοποιημένη" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Η ιδιωτική λειτουργία απενεργοποιήθηκε" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Η προεπιλεγμένη εμφάνιση άλλαξε" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "To όνομα διαδικτύου ρυθμίστηκε επιτυχώς" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "To όνομα διαδικτύου ρυθμίστηκε επιτυχώς" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3655,11 +3632,11 @@ msgstr "" "συνδεθείτε με το διακομιστή, ένας Minetest πελάτη είναι απαραίτητος." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Μπλοκ Sandbox" @@ -3713,7 +3690,7 @@ msgstr "" msgid "Address" msgstr "Διεύθυνση" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3913,7 +3890,7 @@ msgstr "Secure Shell" msgid "Services" msgstr "Υπηρεσία" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3922,7 +3899,7 @@ msgstr "" "Ethernet, Wi-Fi ή PPPoE. Μοιραστείτε αυτήν τη σύνδεση με άλλες συσκευές στο " "δίκτυο." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3930,7 +3907,7 @@ msgstr "" "Οι συσκευές που διαχειρίζονται μέσω άλλων μεθόδων ενδέχεται να μην είναι " "διαθέσιμες για ρύθμιση παραμέτρων εδώ." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Δίκτυα" @@ -4304,7 +4281,7 @@ msgstr "Επεξεργασία σύνδεσης" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Επεξεργασία" @@ -4409,7 +4386,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Μέθοδος" @@ -4425,7 +4402,7 @@ msgstr "Διακομιστής DNS" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Προεπιλογή" @@ -4438,7 +4415,7 @@ msgid "This connection is not active." msgstr "Αυτή η σύνδεση δεν είναι ενεργή." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Ασφάλεια" @@ -5043,7 +5020,7 @@ msgstr "Η σύνδεση {name} διαγράφηκε." msgid "Failed to delete connection: Connection not found." msgstr "Απέτυχε η διαγραφή της σύνδεσης: η σύνδεση δεν βρέθηκε." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -5061,22 +5038,22 @@ msgstr "" "επίσης να αποκτήσετε πρόσβαση στο υπόλοιπο Internet μέσω του {box_name} για " "πρόσθετη ασφάλεια και ανωνυμία." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection Type" msgid "Connect to VPN services" msgstr "Τύπος σύνδεσης" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Εικονικό ιδιωτικό δίκτυο" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5088,50 +5065,21 @@ msgstr " Λήψη προφί msgid "Tunnelblick" msgstr "TunnelBlick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -#, fuzzy -#| msgid "Moderate" -msgid "Migrate" -msgstr "Μέτριο" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Προφίλ" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Για να συνδεθείτε στο VPN του %(box_name)s, πρέπει να κάνετε λήψη ενός " @@ -5141,18 +5089,19 @@ msgstr "" "περισσότερα...\" Προτεινόμενα προγράμματα-πελάτες και οδηγίες σχετικά με τον " "τρόπο διαμόρφωσης τους." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Το προφίλ είναι συγκεκριμένο για κάθε χρήστη του %(box_name)s. Κρατήστε το " "μυστικό." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Λήψη του προφίλ μου" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5165,19 +5114,19 @@ msgstr "" "υπηρεσίες δεν είναι προσβάσιμες από το υπόλοιπο Internet. Αυτό περιλαμβάνει " "τις ακόλουθες καταστάσεις:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "το {box_name} βρίσκεται πίσω από ένα περιορισμένο τείχος προστασίας." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "το {box_name} είναι συνδεδεμένο σε έναν (ασύρματο) δρομολογητή, τον οποίο " "δεν ελέγχετε." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5185,7 +5134,7 @@ msgstr "" "Ο παροχέας ιντερνετ δεν σας παρέχει εξωτερική διεύθυνση IP και αντίθετα " "παρέχει σύνδεση στο Internet μέσω δικτύου NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5193,11 +5142,11 @@ msgstr "" "Ο παροχέας ιντερνετ δεν σας παρέχει μια στατική διεύθυνση IP και η διεύθυνση " "IP αλλάζει κάθε φορά που συνδέεστε στο Internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Ο παροχέας ιντερνετ περιορίζει τις εισερχόμενες συνδέσεις." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5211,23 +5160,23 @@ msgstr "" "παράδειγμα pagekite.net . Στο μέλλον " "μπορεί να είναι δυνατή η χρήση του {box_name} ενός φίλου σας για αυτό." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Δημόσια ορατότητα" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Όνομα διαδικτύου Pagekite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Όνομα διαδικτύου διακομιστή" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5235,31 +5184,31 @@ msgstr "" "Επιλέξτε το διακομιστή pagekite. Ορίστε το \"pagekite.net\" για να " "χρησιμοποιήσετε τον προεπιλεγμένο διακομιστή pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Θύρα διακομιστή" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Θύρα του διακομιστή σελιδοποίησης (προεπιλογή: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite όνομα" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Παράδειγμα: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Μη έγκυρο όνομα kite" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite μυστικό" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5267,27 +5216,27 @@ msgstr "" "Ένα μυστικό που σχετίζεται με το kite ή το προεπιλεγμένο μυστικό για το " "λογαριασμό σας, εάν δεν αναθέσετε καινούριο." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "Πρωτόκολλο" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "εξωτερική (frontend) θύρα" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "εσωτερική (freedombox) θύρα" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Ενεργοποίηση δευτερευόντων ονομάτων διαδικτύου" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Διαγράφηκε η διαμορφωμένη υπηρεσία" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 #, fuzzy #| msgid "" #| "This service is available as a standard service. Please use the " @@ -5297,11 +5246,11 @@ msgstr "" "Αυτή η υπηρεσία είναι διαθέσιμη ως πρότυπη υπηρεσία. Παρακαλούμε να " "χρησιμοποιήσετε την σελίδα \"Πρότυπες Υπηρεσίες\" για να το ενεργοποιήσετε." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Προστέθηκε τροποποιημένη υπηρεσία" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Αυτή η υπηρεσία υπάρχει ήδη" @@ -5339,30 +5288,30 @@ msgstr "" "παράδειγμα, HTTPS, στις θύρες εκτός από 443 είναι γνωστό ότι προκαλούν " "προβλήματα." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Διακομιστής Διαδικτύου (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" "Η τοποθεσία θα είναι διαθέσιμη στο http://{0} " -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Διακομιστής Διαδικτύου (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Το Site θα είναι διαθέσιμο στο https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5409,8 +5358,8 @@ msgstr "" "ενδεχόμενο να περιμένετε μέχρι να ολοκληρωθεί πριν από τον τερματισμό ή την " "επανεκκίνηση." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Κάνετε επανεκκίνηση" @@ -5463,6 +5412,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Τερματισμός τώρα" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5513,7 +5495,7 @@ msgstr "" "Πρόσβαση στη διεύθυνση URL {url} με διακομιστή μεσολάβησης {proxy} στο TCP " "{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5531,7 +5513,7 @@ msgstr "" "πελάτες Κουάσελ από ένα υπολογιστή ή ένα κινητό μπορούν να χρησιμοποιηθούν " "για τη σύνδεση και την αποσύνδεση από αυτό." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your υπολογιστή και κινητό είναι διαθέσιμοι." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Πελάτης IRC" @@ -5555,7 +5537,7 @@ msgstr "Πελάτης IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5575,7 +5557,7 @@ msgstr "" "clients/\">πελάτη . Το Radicale μπορεί να προσεγγιστεί από οποιονδήποτε " "χρήστη με {box_name} πιστοποιητικά." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5586,12 +5568,12 @@ msgstr "" "γεγονότων ή επαφών, το οποίο πρέπει να γίνει χρησιμοποιώντας ένα ξεχωριστό " "πελάτη." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Ημερολόγιο και βιβλίο διευθύνσεων" @@ -5670,7 +5652,7 @@ msgstr "" "κλικ στο κουμπί αναζήτηση σε λίστα με υπάρχοντα ημερολόγια και βιβλία " "διευθύνσεων." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Η διαμόρφωση των δικαιωμάτων πρόσβασης ενημερώθηκε" @@ -5771,7 +5753,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Διαβάστε και εγγραφείτε τροφοδοσίες ειδήσεων" @@ -5784,7 +5766,7 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5792,7 +5774,7 @@ msgstr "" "Το Samba επιτρέπει την κοινή χρήση αρχείων και φακέλων μεταξύ του Freedombox " "και άλλων υπολογιστών στο τοπικό σας δίκτυο." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5807,11 +5789,11 @@ msgstr "" "Υπάρχουν τρεις τύποι κοινόχρηστων αρχείων από τα οποία μπορείτε να " "επιλέξετε: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Ανοιχτό μέρισμα - ορατό σε όλους τους χρήστες του τοπικού δικτύου." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5819,7 +5801,7 @@ msgstr "" "Ομαδικό μέρισμα - ορατό μόνο σε χρήστες του Freedombox που είναι στην ομάδα " "Freedombox-share." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5827,15 +5809,15 @@ msgstr "" "Οικιακό μέρισμα - κάθε χρήστης στην ομάδα freedombox-share μπορεί να έχει το " "δικό του προσωπικό διαμέρισμα στο δίσκο." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Πρόσβαση στα ιδιωτικά μερίσματα" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Distributed File Storage" msgid "Network File Storage" @@ -5938,17 +5920,17 @@ msgstr "Όνομα μερίσματος" msgid "Action" msgstr "Ενέργεια" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "Freedombox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Aνοικτό μέρισμα" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Ομαδικό μέρισμα" @@ -5974,7 +5956,7 @@ msgstr "Το μέρισμα απενεργοποιήθηκε." msgid "Error disabling share: {error_message}" msgstr "Σφάλμα κατά την απενεργοποίηση του μερίσματος: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5983,7 +5965,7 @@ msgstr "" "ιδιωτικότητα. Μαζεύει και εμφανίζει αποτελέσματα από πολλαπλές μηχανές " "αναζήτησης." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5992,41 +5974,41 @@ msgstr "" "δημιουργία προφίλ χρήστη από τις μηχανές αναζήτησης. Δεν αποθηκεύει cookies " "από προεπιλογή." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Αναζήτηση στο διαδίκτυο" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Διαδικτυακή αναζήτηση" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Ασφαλής αναζήτηση" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Επιλέξτε το οικογενειακό φίλτρο που θα εφαρμοστεί στα αποτελέσματα " "αναζήτησης." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Μέτριο" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Αυστηρό" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Να επιτρέπεται δημόσια πρόσβαση" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Να επιτρέπεται η χρήση αυτής της εφαρμογής από οποιονδήποτε μπορεί να την " @@ -6213,7 +6195,7 @@ msgstr "Σελιδοδείκτες" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6223,7 +6205,7 @@ msgstr "" "σκοπό να προστατεύσει την κίνησή σας στο διαδίκτυο. Μπορεί να χρησιμοποιηθεί " "για να παρακάμψει το φιλτράρισμα στο Διαδίκτυο και τη λογοκρισία." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6237,7 +6219,7 @@ msgstr "" "διακομιστή μεσολάβησης και τα δεδομένα τους θα κρυπτογραφηθούν και θα " "αποσταλούν μέσω του διακομιστή shadowsocks." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6247,43 +6229,43 @@ msgstr "" "την εφαρμογή που επιθυμείτε στη διεύθυνση του freedomox http: // " "freedombox_address: 1080 /" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Διακομιστής μεσολάβησης τύπου socks5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Συνιστάται" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Διακομιστής" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Όνομα διακομιστή ή διεύθυνση IP" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Αριθμός θύρας διακομιστή" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Κωδικός πρόσβασης που χρησιμοποιείται για την κρυπτογράφηση δεδομένων. " "Πρέπει να ταιριάζει με τον κωδικό πρόσβασης του διακομιστή." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" "Μέθοδος κρυπτογράφησης. Πρέπει να ταιριάζει με τη ρύθμιση στο διακομιστή." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6292,15 +6274,15 @@ msgstr "" "To Sharing σάς επιτρέπει να μοιράζεστε αρχεία και φακέλους στο {box_name} " "μέσω του διαδικτύου με επιλεγμένες ομάδες χρηστών." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Κοινή χρήση" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Όνομα του κοινόχρηστου στοιχείου" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6308,31 +6290,31 @@ msgstr "" "Μια αλφαριθμητική συμβολοσειρά (μικρά γράμματα) που προσδιορίζει με μοναδικό " "τρόπο ένα κοινόχρηστο στοιχείο. Παράδειγμα: πολυμέσα ." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Μονοπάτι που θα μοιραστείτε" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Μονοπάτι δίσκου σε αυτό το διακομιστή που σκοπέυετε να μοιραστείτε." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Μοιραστείτε δημόσια" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" "Κάνουν τα αρχεία σε αυτόν το φάκελο διαθέσιμα σε οποιονδήποτε διαθέτει το " "σύνδεσμο." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 #, fuzzy #| msgid "User groups that can read the files in the share" msgid "User groups that can read the files in the share:" msgstr "Ομάδες χρηστών που μπορούν να διαβάσουν τα αρχεία στο μέρισμα" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6340,11 +6322,11 @@ msgstr "" "Οι χρήστες των επιλεγμένων ομάδων χρηστών θα μπορούν να διαβάσουν τα αρχεία " "στο μέρισμα." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Υπάρχει ήδη ένα μέρισμα με αυτό το όνομα." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" "Τα μερίσματα θα πρέπει να είναι είτε δημόσια είτε να μοιράζονται με " @@ -6383,19 +6365,19 @@ msgstr "Το μέρισμα προστέθηκε." msgid "Add Share" msgstr "Προσθήκη μερίσματος" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Το μέρισμα ρυθμίστηκε." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Επεξεργασία μερίσματος" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Το μέρισμα διαγράφηκε." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6406,7 +6388,7 @@ msgstr "" "σε μια προηγουμένως γνωστή καλή κατάσταση σε περίπτωση ανεπιθύμητων αλλαγών " "στο σύστημα." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6417,7 +6399,7 @@ msgstr "" "και επίσης πριν και μετά από μια εγκατάσταση λογισμικού. Τα παλαιότερα " "στιγμιότυπα θα καθαρίζονται αυτόματα σύμφωνα με τις παρακάτω ρυθμίσεις." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for αντίγραφα ασφαλείας επειδή " "μπορούν να αποθηκευτούν μόνο στο ίδιο διαμέρισμα του δίσκου. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Στιγμιότυπα συστήματος αρχείων" @@ -6537,7 +6519,7 @@ msgstr "Ημερομηνία" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Διαγραφή στιγμιότυπων" @@ -6595,62 +6577,62 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Επαναφορά στο στιγμιότυπο #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Repository created." msgid "manually created" msgstr "Το αποθετήριο δημιουργήθηκε." -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Διαχείριση στιγμιότυπων" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Το στιγμιότυπο δημιουργήθηκε." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Η ρύθμιση παραμέτρων των στιγμιότυπων αποθήκευσης Ενημερώθηκε" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Σφάλμα ενέργειας: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Διαγράφηκαν επιλεγμένα στιγμιότυπα" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" "Το στιγμιότυπο χρησιμοποιείται αυτήν τη στιγμή. Παρακαλώ προσπαθήστε ξανά " "αργότερα." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Πραγματοποιήθηκε επαναφορά στο στιγμιότυπο #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" "Πρέπει να γίνει επανεκκίνηση του συστήματος για να ολοκληρωθεί η επαναφορά." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Επαναφορά σε στιγμιότυπο" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6663,7 +6645,7 @@ msgstr "" "αντιγράψει αρχεία ή να εκτελέσει άλλες υπηρεσίες χρησιμοποιώντας αυτές τις " "συνδέσεις." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Διακομιστής SSH" @@ -6702,14 +6684,6 @@ msgstr "Αλγόριθμος" msgid "Fingerprint" msgstr "Ψηφιακό αποτύπωμα" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "Έλεγχος ταυτότητας SSH με κωδικό πρόσβασης απενεργοποιήθηκε." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Έλεγχος ταυτότητας SSH με κωδικό πρόσβασης ενεργοποιήθηκε." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Ενιαία είσοδος" @@ -6724,7 +6698,7 @@ msgstr "Σύνδεση" msgid "Logged out successfully." msgstr "Ο κωδικός πρόσβασης άλλαξε με επιτυχία." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6736,92 +6710,92 @@ msgstr "" "χρησιμοποιούνται προς το παρόν, να προσθέσετε και να αφαιρέσετε αφαιρούμενα " "μέσα, επεκτείνετε το root διαμέρισμα κλπ." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Χώρος Αποθήκευσης" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bytes" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Η ενέργεια απέτυχε." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Η ενέργεια ακυρώθηκε." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Η συσκευή είναι ήδη προς αφαίρεση." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "Η ενέργεια δεν υποστηρίζεται λόγω μη υποστήριξης προγραμματος οδηγού." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Η ενέργεια απέτυχε επειδή διήρκησε πολύ χρόνο." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" "Η ενέργεια θα ξυπνήσει ένα δίσκο που είναι σε μια βαθιά κατάσταση ύπνου." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Γίνεται προσπάθεια αφαίρεσης μιας συσκευής που είναι απασχολημένη." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Η ενέργια έχει ήδη ακυρωθεί." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Δεν έχετε εξουσιοδότηση για την εκτέλεση της συγκεκριμένης ενέργειας." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Η συσκευή έχει ήδη προστεθεί." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Η συσκευή δεν είναι τοποθετημένη." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Δεν έχετε εξουσιοδότηση για την εκτέλεση της συγκεκριμένης ενέργειας." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Η συσκευή έχει ήδη προστεθεί από άλλο χρήστη." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, fuzzy, no-python-format, python-brace-format #| msgid "" #| "Warning: Low space on system partition ({percent_used}% used, " @@ -6831,54 +6805,54 @@ msgstr "" "Προειδοποίηση: χαμηλός χώρος στο διαμέρισμα του συστήματος ({percent_used}% " "χρησιμοποιείται, {free_space} είναι ελεύθερος)." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Το όνομα καταλόγου δεν είναι έγκυρο." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Ο κατάλογος δεν υπάρχει." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Το μονοπάτι δεν είναι κατάλογος." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Ο κατάλογος δεν είναι αναγνώσιμος από τον χρήστη." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Ο κατάλογος δεν είναι εγγράψιμος από το χρήστη." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Κατάλογος" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Υποκατάλογος (προαιρετικό)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Κοινοποίηση" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Άλλος κατάλογος (Καθορίστε παρακάτω)" @@ -6915,7 +6889,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Επεκτείνετε το διαμέρισμα root" @@ -6936,30 +6910,30 @@ msgstr "" "προχωρήσετε. Μετά από αυτήν τηv ενέργεια, %(expandable_root_size)s του " "ελεύθερου χώρου θα είναι διαθέσιμο στο root διαμέρισμα." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Σφάλμα επέκτασης του διαμερίσματος: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Το διαμέρισμα επεκτάθηκε με επιτυχία." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} μπορεί να αποσυνδεθεί με ασφάλεια." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Η συσκευή μπορεί να αποσυνδεθεί με ασφάλεια." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Σφάλμα κατά την αφαίρεση της συσκευής: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6971,7 +6945,7 @@ msgstr "" "δημιουργία, η τροποποίηση ή η διαγραφή αρχείων σε μία συσκευή θα αναπαραχθεί " "αυτόματα σε όλες τις άλλες συσκευές που εκτελούν επίσης το Syncthing." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, fuzzy, python-brace-format #| msgid "" #| "Running Syncthing on {box_name} provides an extra synchronization point " @@ -6998,20 +6972,20 @@ msgstr "" "{box_name} είναι διαθέσιμη μόνο για χρήστες που ανήκουν στην ομάδα \"admin" "\" (διαχειριστών)." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Διαχειριστείτε την εφαρμογή Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Συγχρονισμός αρχείων" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -7025,7 +6999,7 @@ msgstr "" "Project συνιστά να χρησιμοποιήσετε το πρόγραμμα περιήγησης διαδικτύου Tor." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, fuzzy, python-brace-format #| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." msgid "" @@ -7033,40 +7007,40 @@ msgid "" "TCP port 9050." msgstr "Μια θύρα Tor SOCKS είναι διαθέσιμη στη θύρα 9050 του %(box_name)s σας." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Υπηρεσία κρεμυδιού Tor" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor διακομιστής μεσολάβησης τύπου socks5" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Γέφυρα/μεσολαβητής Tor" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Θύρα μεσολαβητή Tor διαθέσιμη" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 μεταφορά καταχωρήθηκε" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 μεταφορά καταχωρήθηκε" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Πρόσβαση στη διεύθυνση URL {url} με tcp {kind} μέσω του Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Επιβεβαίωση χρήσης του Tor στο {url} στο προτόκολλο TCP {kind}" @@ -7189,13 +7163,13 @@ msgstr "Υπηρεσία κρεμμυδιού" msgid "Ports" msgstr "Θύρες" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Παρουσιάστηκε σφάλμα κατά τη ρύθμιση παραμέτρων." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -7257,7 +7231,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7267,7 +7241,7 @@ msgstr "" "σχεδιασμένος να επιτρέπει την ανάγνωση ειδήσεων από οποιαδήποτε τοποθεσία, " "ενώ δίνει την εντύπωση μιας πραγματικής εφαρμογής επιφάνειας εργασίας." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS can be accessed by any χρήστη με {box_name} πιστοποιητικά." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 #, fuzzy #| msgid "" #| "When using a mobile or desktop application for Tiny Tiny RSS, use the URL " @@ -7293,11 +7267,11 @@ msgstr "" "Tiny Tiny RSS, χρησιμοποιήστε τη διεύθυνση URL /tt-rss-app για τη σύνδεση." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Αναγνώστης ειδήσεων" @@ -7305,13 +7279,13 @@ msgstr "Αναγνώστης ειδήσεων" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Ελέγξτε και εφαρμόστε τις πιο πρόσφατες ενημερώσεις λογισμικού και ασφαλείας." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7319,8 +7293,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -7328,30 +7302,30 @@ msgstr "" msgid "Software Update" msgstr "Το μέρισμα διαγράφηκε." -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox Foundation" msgid "FreedomBox Updated" msgstr "Ίδρυμα FreedomBox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution update started" msgstr "Oι αυτόματες ενημερώσεις απενεργοποιήθηκαν" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7539,50 +7513,50 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Oι αυτόματες ενημερώσεις ενεργοποιήθηκαν" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Σφάλμα κατά τη ρύθμιση των αυτόματων ενημερώσεων: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Oι αυτόματες ενημερώσεις ενεργοποιήθηκαν" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Oι αυτόματες ενημερώσεις απενεργοποιήθηκαν" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Distribution upgrade enabled" msgstr "Oι αυτόματες ενημερώσεις ενεργοποιήθηκαν" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution upgrade disabled" msgstr "Oι αυτόματες ενημερώσεις απενεργοποιήθηκαν" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Ξεκίνησε η διαδικασία αναβάθμισης." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Η εκκίνηση της αναβάθμισης απέτυχε." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Starting distribution upgrade test." msgstr "Oι αυτόματες ενημερώσεις ενεργοποιήθηκαν" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 #, fuzzy #| msgid "" #| "Create and managed user accounts. These accounts serve as centralized " @@ -7599,7 +7573,7 @@ msgstr "" "είναι μέρος μιας ομάδας για να εξουσιοδοτήσουν το χρήστη να αποκτήσει " "πρόσβαση στην εφαρμογή." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7611,15 +7585,15 @@ msgstr "" "σελίδα. Ωστόσο, μόνο οι χρήστες της ομάδας admin μπορούν να " "τροποποιήσουν τις εφαρμογές ή τις ρυθμίσεις του συστήματος." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Χρήστες και ομάδες" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Πρόσβαση σε όλες τις υπηρεσίες και τις ρυθμίσεις συστήματος" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Ελέγξτε την καταχώρηση LDAP \"{search_item}\"" @@ -7639,25 +7613,25 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Password" msgid "Authorization Password" msgstr "Κωδικός Πρόσβασης Διαχειριστή" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "Εμφάνιση κωδικού" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 #, fuzzy #| msgid "" #| "Select which services should be available to the new user. The user will " @@ -7679,13 +7653,13 @@ msgstr "" "υπηρεσίες. Μπορούν επίσης να συνδεθούν στο σύστημα μέσω του SSH και να έχουν " "δικαιώματα διαχειριστή (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, fuzzy, python-brace-format #| msgid "Creating LDAP user failed." msgid "Creating LDAP user failed: {error}" msgstr "Η δημιουργία χρήστη LDAP απέτυχε." -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, fuzzy, python-brace-format #| msgid "Failed to add new user to {group} group." msgid "Failed to add new user to {group} group: {error}" @@ -7706,43 +7680,43 @@ msgstr "" "Μπορείτε να εισαγάγετε πολλαπλά κλειδιά, ένα σε κάθε γραμμή. Οι κενές " "γραμμές και οι γραμμές που ξεκινούν με # θα αγνοηθούν." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Η μετονομασία του χρήστη LDAP απέτυχε." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Απέτυχε η κατάργηση του χρήστη από την ομάδα." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Απέτυχε η προσθήκη χρήστη στην ομάδα." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Δεν ήταν δυνατό να προστεθούν τα κλειδιά SSH." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Απέτυχε η αλλαγή της κατάστασης χρήστη." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Η αλλαγή του κωδικού πρόσβασης χρήστη LDAP απέτυχε." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, fuzzy, python-brace-format #| msgid "Failed to add new user to admin group." msgid "Failed to add new user to admin group: {error}" msgstr "Αποτυχία προσθήκης νέου χρήστη στην ομάδα διαχειριστών." -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, fuzzy, python-brace-format #| msgid "Failed to restrict console access." msgid "Failed to restrict console access: {error}" msgstr "Απέτυχε ο περιορισμός της πρόσβασης στην κονσόλα." -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Ο λογαριασμός χρήστη δημιουργήθηκε, τώρα είστε συνδεδεμένοι" @@ -7759,12 +7733,12 @@ msgstr "Αποθήκευση κωδικού πρόσβασης" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Δημιουργία χρήστη" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Διαγραφή χρήστη" @@ -7810,17 +7784,17 @@ msgid "The following administrator accounts exist in the system." msgstr "Δεν είναι δυνατή η διαγραφή του μοναδικού διαχειριστή στο σύστημα." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Χρήστες" @@ -7854,34 +7828,34 @@ msgstr "" msgid "Save Changes" msgstr "Αποθήκευση αλλαγών" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Ο χρήστης %(username)s δημιουργήθηκε." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "O χρήστης %(username)s ενημερώθηκε." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Επεξεργασία χρήστη" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Ο χρήστης {user} διαγράφηκε." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Η διαγραφή του χρήστη LDAP απέτυχε." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Αλλαγή κωδικού πρόσβασης" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Ο κωδικός πρόσβασης άλλαξε με επιτυχία." @@ -8254,7 +8228,7 @@ msgstr "Διαγραφή σύνδεσης" msgid "Server deleted." msgstr "Το μέρισμα διαγράφηκε." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8263,7 +8237,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8272,28 +8246,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "Διεύθυνση" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki and Blog" msgid "Website and Blog" @@ -8311,7 +8285,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8324,7 +8298,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8332,11 +8306,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -8388,116 +8362,110 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing Backups" -msgid "Error running apt-get" -msgstr "Υπάρχοντα αντίγραφα ασφαλείας" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "Εγκαθίσταται" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "Λήψη" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "Αλλαγή μέσου" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "αρχείο ρυθμίσεων: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Εγκαταστήσετε Εφαρμογές" -#: plinth/setup.py:42 +#: plinth/setup.py:43 #, fuzzy #| msgid "Updating..." msgid "Updating app" msgstr "Eνημερώνεται..." -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Σφάλμα κατά την εγκατάσταση της εφαρμογής: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Σφάλμα κατά την εγκατάσταση της εφαρμογής: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Σφάλμα κατά την εγκατάσταση της εφαρμογής: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Σφάλμα κατά την εγκατάσταση της εφαρμογής: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Η εφαρμογή εγκαταστάθηκε." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Τελευταία ενημέρωση" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Εγκαταστήσετε Εφαρμογές" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Σφάλμα κατά την εγκατάσταση της εφαρμογής: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Σφάλμα κατά την εγκατάσταση της εφαρμογής: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Η εφαρμογή εγκαταστάθηκε." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -8570,53 +8538,54 @@ msgstr "Εγκατάσταση" msgid "Service %(service_name)s is not running." msgstr "Η υπηρεσία %(service_name)s δεν εκτελείται." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Βασική λειτουργικότητα και σελίδα ιστού για το %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Κεντρική σελίδα" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Κεντρική σελίδα" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Εφαρμογές" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Εφαρμογές" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Σύστημα" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Σύστημα" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Αλλαγή κωδικού πρόσβασης" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "ΤΕΡΜΑΤΙΣΜΟΣ ΛΕΙΤΟΥΡΓΙΑΣ" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Αποσύνδεση" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Επιλογή γλώσσας" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Σύνδεση" @@ -8917,6 +8886,48 @@ msgstr "" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Ενεργοποίηση DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "" +#~ "Ενεργοποίηση επεκτάσεων ασφαλείας για διακομιστές ονομάτων διαδικτύου " +#~ "(DNS)" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "To πρόγραμμα τείχους προστασίας δεν εκτελείται. Παρακαλείστε να το " +#~ "τρέξετε. Το τείχος προστασίας εμφανίζεται ενεργοποιημένο από προεπιλογή " +#~ "στο %(box_name)s. Σε οποιοδήποτε σύστημα που βασίζεται στο Debian (όπως " +#~ "το %(box_name)s) μπορείτε να το εκτελέσετε χρησιμοποιώντας την εντολή ' " +#~ "service firewalld start ' ή σε περίπτωση ενός συστήματος με systemd ' " +#~ "systemctl start firewalld '." + +#, fuzzy +#~| msgid "Moderate" +#~ msgid "Migrate" +#~ msgstr "Μέτριο" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "Έλεγχος ταυτότητας SSH με κωδικό πρόσβασης απενεργοποιήθηκε." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Έλεγχος ταυτότητας SSH με κωδικό πρόσβασης ενεργοποιήθηκε." + +#, fuzzy +#~| msgid "Existing Backups" +#~ msgid "Error running apt-get" +#~ msgstr "Υπάρχοντα αντίγραφα ασφαλείας" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Βασική λειτουργικότητα και σελίδα ιστού για το %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Συνδέσεις δικτύου" diff --git a/plinth/locale/es/LC_MESSAGES/django.po b/plinth/locale/es/LC_MESSAGES/django.po index 3ad209ea4..335e4cc70 100644 --- a/plinth/locale/es/LC_MESSAGES/django.po +++ b/plinth/locale/es/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Spanish calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1052,23 +1045,23 @@ msgstr "" "Solo los usuarios del grupo calibre podrán acceder a la app. Todos " "los usuarios con acceso pueden usar todas las bibliotecas." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Usar bibliotecas Calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "Calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Biblioteca de libros electrónicos" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Nombre de la nueva biblioteca" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1076,7 +1069,7 @@ msgstr "" "Solo letras sin tilde, números, punto y guiones (- ó _), sin espacios, ni Ñ, " "ni Ç. Ejemplo: Mi_biblioteca_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Ya existe una biblioteca con este nombre." @@ -1124,20 +1117,20 @@ msgstr "Ir a biblioteca %(library)s" msgid "Delete library %(library)s" msgstr "Eliminar biblioteca %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Biblioteca creada." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Ha habido un error al crear la biblioteca." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} eliminado." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "No se pudo eliminar {name}: {error}" @@ -1185,7 +1178,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Administración del servidor" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1193,18 +1186,18 @@ msgstr "" "Opciones de configuración general como el nombre del host, el del dominio, " "la página de inicio del servidor web, etc." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Configuración general" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Configurar" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1322,47 +1315,47 @@ msgstr "" "Los registros de ejecución contienen información de quién accedió al sistema " "y detalles para depuración de varios servicios" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Error al definir el nombre de anfitrión: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Asignar nombre de anfitrión" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Error al establecer nombre de dominio: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Asignar nombre de dominio" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Error al configurar la página de inicio del servidor web: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Página de inicio del servidor web configurada" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Error al cambiar al modo avanzado: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Mostrando aplicaciones y funciones avanzadas" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Ocultando aplicaciones y funciones avanzadas" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1374,7 +1367,7 @@ msgstr "" "SIP y de otros tipos pueden usarlo para establecer llamadas entre partes que " "no tienen otra alternativa disponible." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ejabberd tienen que configurarse con los detalles que se " "proporcionan aquí." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Asistente VoIP" @@ -1447,11 +1440,11 @@ msgstr "Error al definir zona horaria: {exception}" msgid "Time zone set" msgstr "Zona horaria asignada" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge es un cliente BitTorrent con interfaz web." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1459,16 +1452,16 @@ msgstr "" "La clave de acceso por defecto es 'deluge' pero es muy recomendable que nada " "más activar el servicio acceda al mismo y la cambie." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Descargar archivos usando aplicaciones BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Cliente web de BitTorrent" @@ -1595,7 +1588,7 @@ msgstr "Resultado" msgid "Diagnostic Test" msgstr "Test de diagnóstico" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1606,7 +1599,7 @@ msgstr "" "24h) será muy difícil para los demás encontrarle en Internet. Este servicio " "permitirá a otros encontrar los servicios que ofrece {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1623,7 +1616,7 @@ msgstr "" "asigna su nombre DNS a esta nueva IP de forma que cualquiera que pida su " "nombre DNS obtendrá la dirección IP actualizada." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1636,11 +1629,11 @@ msgstr "" "de actualización en freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Cliente de DNS dinámico" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Nombre de dominio dinámico" @@ -1767,7 +1760,7 @@ msgstr "Este campo es obligatorio." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1822,7 +1815,7 @@ msgstr "El Servidor rechazo la conexión" msgid "Already up-to-date" msgstr "Ya Estaba Actualizada" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1830,7 +1823,7 @@ msgstr "" "XMPP es un protocolo de comunicación abierto y estándar. Puede ejecutar y " "configurar su servidor XMPP (ejabberd) aquí." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientcliente XMPP. Cuando se activa, ejabberd está disponible para " "cualquier usuario con acceso a {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn o configurar un servidor " "externo." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Servidor de Chat" @@ -1979,7 +1972,7 @@ msgstr "" "será parecida a username@%(domainname)s. Puede configurar su dominio " "en la página de sistema Configurar." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1990,7 +1983,7 @@ msgstr "" "Dovecot permite que los clientes de correo electrónico accedan a su buzón " "mediante IMAP y POP3. Rspamd se ocupa del spam." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2002,7 +1995,7 @@ msgstr "" "proveedores de internet también restringen el correo saliente. Algunos " "levantan la restricción a demanda. Más información en la página del manual." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2017,7 +2010,7 @@ msgstr "" "a su dirección de correo electrónico. Los alias necesarios como \"postmaster" "\" se crean automáticamente apuntando al primer usuario administrador." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2025,7 +2018,7 @@ msgstr "" "Roundcube app proporciona un " "interfaz web para que los usuarios accedan a correo electrónico." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2156,7 +2149,7 @@ msgstr "Puerto" msgid "Host/Target/Value" msgstr "Host/Objetivo/Valor" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2167,7 +2160,7 @@ msgstr "" "de su {box_name}. Mantenerlo activado y correctamente configurado reduce el " "riesgo de amenazas de seguridad desde Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Cortafuegos" @@ -2187,52 +2180,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Puerto {name} ({details}) no disponible para redes externas" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"El servicio firewall no se está ejecutando. Por favor actívelo. El firewall " -"viene activado por defecto en su %(box_name)s. En cualquier sistema basado " -"en Debian (como %(box_name)s) puede activarlo con 'service firewalld start' " -"o si su sistema emplea systemd 'systemctl start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Servicio/Puerto" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Activado" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Desactivado" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Permitido" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Permitido (solo interno)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Permitido (solo externo)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Bloqueado" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2242,13 +2222,13 @@ msgstr "" "se autoriza en el firewall, y cuando lo desactiva también se desactiva en el " "firewall." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Avanzado" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2303,7 +2283,7 @@ msgstr "Iniciar configuración" msgid "Setup Complete" msgstr "Configuración completada" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2321,7 +2301,7 @@ msgstr "" "cliente Git de línea de comandos o múltiples clientes gráficos. Y puedes " "compartir tu código con gente de todo el mundo." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2329,68 +2309,68 @@ msgstr "" "Para aprender más acerca de cómo usar Git visita el tutorial de Git." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Acceso de lectura y escritura para repositorios Git" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Alojamiento simple para Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "URL de repositorio no válida." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Nombre de repositorio no válido." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Nombre de un nuevo repositorio o URL para importar un repositorio existente." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Descripción del repositorio" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Opcional, para mostrar en Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Nombre del dueño del repositorio" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Repositorio privado" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Permitir acceder a este repositorio sólo a usuarios autorizados." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Ya existe un repositorio con este nombre." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Nombre del repositorio" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Una cadena alfanumérica que identifica unívocamente un repositorio." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Rama por omisión" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb muestra esta rama por omisión." @@ -2434,19 +2414,19 @@ msgstr "Borrar Repositorio Git %(name)s" msgid "Delete this repository permanently?" msgstr "¿Eliminar este repositorio definitivamente?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Repositorio creado." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Ha habido un error al crear el repositorio." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Repositorio editado." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Editar repositorio" @@ -2808,7 +2788,7 @@ msgstr "Acerca de {box_name}" msgid "{box_name} Manual" msgstr "Manual de {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2820,7 +2800,7 @@ msgstr "" "anonimato al enviar trafico cifrado a través de una red mantenida por " "voluntarios alrededor del mundo." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2828,7 +2808,7 @@ msgstr "" "Para ampliar información sobre I2P visite el sitio web del proyecto." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2836,19 +2816,19 @@ msgstr "" "La primer visita a la interfaz web provista iniciará el proceso de " "configuración." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Administrar la aplicación I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Red anónima" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "Proxy I2P" @@ -2894,7 +2874,7 @@ msgstr "" "red par-a-par. Descarga los archivos al agregar los torrents o crea un nuevo " "torrent para compartir un archivo." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2904,7 +2884,7 @@ msgstr "" "de marcado, Markdown incluido, y funcionalidades comunes de los blogs tal " "como comentarios o fuentes RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2918,15 +2898,15 @@ msgstr "" "\"{users_url}\">configuración de usuarios puede modificar estos permisos " "o añadir nuevos usuarios." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki y Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Aplicaciones wiki para ver y editar" @@ -2982,41 +2962,41 @@ msgstr "" "Esta acción borrará todas las entradas, páginas y comentarios incluido el " "historial. ¿Eliminar este wiki o blog definitivamente?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Wiki {name} creado." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "No se pudo crear el wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blog {name} creado." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "No se pudo crear el blog: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} eliminado." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "No se pudo eliminar {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted es un servidor para Gobby, un editor de texto colaborativo." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3028,11 +3008,11 @@ msgstr "" "seleccione \"Conectar al servidor\" e introduzca el nombre de dominio de su " "{box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Servidor Gobby" @@ -3080,7 +3060,7 @@ msgstr "Sala de vídeo Janus" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Información de licencia de JavaScript" @@ -3100,7 +3080,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Cliente de Chat" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3115,7 +3095,7 @@ msgstr "" "mostrándose a sí mismo como propietario de un dominio a Let's Encrypt, " "autoridad de certificación (CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3128,15 +3108,15 @@ msgstr "" "letsencrypt.org/repository/\">Acuerdo de suscripción de Let's Encrypt " "antes de usar este servicio." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certificados" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "No puedo probar: No hay dominios configurados." @@ -3201,7 +3181,7 @@ msgstr "" "No se ha configurado ningún dominio. Configure " "alguno para poder asignarle un certificado." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3210,34 +3190,34 @@ msgstr "" "El certificado para el dominio {domain} ha sido revocado con éxito. " "Necesitará unos momentos para tener efecto." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Falló la revocación del certificado para el dominio {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Se ha obtenido con éxito el certificado para el dominio {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Falló la obtención del certificado para el dominio {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "El certificado para el dominio {domain} ha sido eliminado con éxito" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Falló la eliminación del certificado para el dominio {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3254,7 +3234,7 @@ msgstr "" "funcionar. La federación de los servidores permite que las/os usuarias/os de " "un servidor Matrix contacten con los de otro servidor." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3264,7 +3244,7 @@ msgstr "" "Instalar la app Coturn o configurar un servidor " "externo." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3371,7 +3351,7 @@ msgstr "" "TLS válido. Vaya a Let's Encrypt para " "obtener uno." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3383,7 +3363,7 @@ msgstr "" "colaboración. Puede usar MediaWiki para alojar un sitio tipo wiki, tomar " "notas o colaborar en proyectos con otras personas." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3397,7 +3377,7 @@ msgstr "" "MediaWiki en la página Special:CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3405,12 +3385,12 @@ msgstr "" "Cualquiera con acceso a este wiki puede leerlo, pero solo quien se " "autentique en el sistema podrá modificar el contenido." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3494,35 +3474,35 @@ msgid "Password update failed. Please choose a stronger password" msgstr "" "Falló la actualización de la contraseña. Use otra contraseña más fuerte" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Habilitado el registro público" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Inhabilitado el registro público" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Activado el modo privado" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Desactivado el modo privado" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Tema por defecto cambiado" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Nombre de dominio actualizado" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Nombre de sitio actulizado" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3535,11 +3515,11 @@ msgstr "" "defecto (30000). Para acceder al servidor necesitará un Cliente Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Sandbox de bloques" @@ -3592,7 +3572,7 @@ msgstr "" msgid "Address" msgstr "Dirección" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3776,7 +3756,7 @@ msgstr "Intérprete de órdenes seguro" msgid "Services" msgstr "Servicios" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3784,7 +3764,7 @@ msgstr "" "Configurar dispositivos de red. Conectar con Internet mediante Ethernet, Wi-" "Fi o PPPoE. Compartir esa conexión con otros dispositivos de la red." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3792,7 +3772,7 @@ msgstr "" "Los dispositivos administrados mediante otros métodos quizá no estén " "disponibles para configurarse aquí." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Redes" @@ -4222,7 +4202,7 @@ msgstr "Editar conexión" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Editar" @@ -4327,7 +4307,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Método" @@ -4343,7 +4323,7 @@ msgstr "Servidor DNS" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Por defecto" @@ -4356,7 +4336,7 @@ msgid "This connection is not active." msgstr "Esta conexión no está activa." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Protección" @@ -4939,7 +4919,7 @@ msgstr "Conexión {name} eliminada." msgid "Failed to delete connection: Connection not found." msgstr "Ha fallado la eliminación de la conexión: no se encontró." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4956,20 +4936,20 @@ msgstr "" "forma privada. También puede acceder a Internet a través de su {box_name} " "para añadir protección y anonimato." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Conectar a servicios VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Red privada virtual" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4980,58 +4960,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Migrar a crioptografía ECC (basada en curvas elípticas)" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Actualmemte tu instalación OpenVPN está usando RSA. Cambiar a Criptografía " -"de Curva Elíptica (ECC) mejora la velocidad y seguridad al establecer " -"conexiones. Esta operación es irreversible. En la mayoría de computadores " -"monoplaca debería tardar escasos minutos." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Todas las instalaciones nuevas de OpenVPN sobre %(box_name)s usarán ECC de " -"serie. Recomendamos migrar cuanto antes." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Aviso: Esta operación invalidará los perfiles de cliente existentes. " -"Todos los usuarios de OpenVPN en %(box_name)s tienen que descargar sus " -"perfiles nuevos. Para conectar con este servidor tendrán que usar clientes " -"OpenVPN compatibles con ECC." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migrar" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Perfil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Para conectar a la VPN de %(box_name)s necesita descargar un perfil y " @@ -5040,18 +4983,19 @@ msgstr "" "\"Aprender más...\" para información sobre los clientes recomendados y cómo " "configurarlos." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "El perfil es específico de cada usuaria/o de %(box_name)s. Manténgalo en " "secreto." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Descargar mi perfil" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5064,18 +5008,18 @@ msgstr "" "servicios de su {box_name} no son accesibles desde Internet. Esto incluye " "las siguientes situaciones:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} está detrás de un firewall restringido." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} está conectado a un router (inalámbrico) que usted no controla." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5083,7 +5027,7 @@ msgstr "" "Su proveedor de servicio no le da una dirección IP externa y, por el " "contrario, le facilita conexión a Internet a través de un NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5091,11 +5035,11 @@ msgstr "" "Su proveedor de servicios no le da una dirección IP estática por lo que su " "IP cambia cada vez que se conecta a Internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Su proveedor de servicios limita las conexiones entrantes." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5108,23 +5052,23 @@ msgstr "" "de servicios pagekite, por ejemplo pagekite." "net. En el futuro será posible usar su amigable {box_name} para esto." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Visibilidad pública" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Dominio PageKite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Dominio del servidor" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5132,31 +5076,31 @@ msgstr "" "Seleccione su servidor pagekite. Elija \"pagekite.net\" para usar el " "servidor pagekite por defecto." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Puerto del servidor" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Puerto de su servidor pagekite (por defecto es 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Nombre Kite" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Ejemplo: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Nombre de kite inválido" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Clave para Kite" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5164,35 +5108,35 @@ msgstr "" "Una clave asociada al Kite o la clave por defecto para su cuenta si no se " "especifica ninguna." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protocolo" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "puerto externo (frontend)" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "puerto interno (freedombox)" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Activar subdominios" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Servicio personalizado eliminado" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Este servicio ya está disponible como servicio estándar." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Servicio personalizado añadido" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Este servicio ya existe" @@ -5230,29 +5174,29 @@ msgstr "" "Por ejemplo, se sabe que HTTPS en un puerto distinto de 443 causará " "problemas." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Servidor Web (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "El sitio estará disponible en http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Servidor web seguro (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "El sitio estará disponible en https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Intérprete de órdenes seguro (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5303,8 +5247,8 @@ msgstr "" "Otra instalación o actualización está actualmente en ejecución. Por favor " "espere unos momentos antes de apagar o reiniciar." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Reiniciar" @@ -5354,6 +5298,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Apagar ahora" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5395,7 +5372,7 @@ msgstr "Proxy Web" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Acceso a {url} con proxy {proxy} en tcp {kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5412,7 +5389,7 @@ msgstr "" "conectado de forma que distintos clientes Quassel pueden conectarse y " "desconectarse de este servidor desde un ordenador de escritorio o un móvil." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your escritorio y móvil." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Cliente IRC" @@ -5436,7 +5413,7 @@ msgstr "Cliente IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5451,7 +5428,7 @@ msgstr "" "supported-clients\">aplicación cliente soportada. Cualquier persona " "autenticada en {box_name} puede acceder a Radicale." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5461,12 +5438,12 @@ msgstr "" "de nuevos calendarios y agendas. No soporta añadir eventos o contactos, que " "debe hacerse usando un cliente separado." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Calendario y Contactos" @@ -5540,7 +5517,7 @@ msgstr "" "freedombox>) y su nombre de usuario. Pulsando en el botón de búsqueda le " "mostrará un listado de los calendarios y agendas existentes." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Configuración de derechos de acceso actualizada" @@ -5632,7 +5609,7 @@ msgstr "" "seguir varios sitios web. Habilita la autenticación y usa tus credenciales " "de {box_name} al añadir un feed." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Leer y suscribirse a nuevos agregadores" @@ -5645,7 +5622,7 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "Generador de feeds RSS" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5653,7 +5630,7 @@ msgstr "" "Samba permite compartir archivos y carpetas entre FreedomBox y otras " "computadoras en su red local." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5666,11 +5643,11 @@ msgstr "" "la dirección \\\\{hostname} (en Windows) o smb://{hostname}.local (en Linux " "y Mac). Puede elegir entre tres tipos para compartir: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Compartir en abierto - accesible para todo el mundo en su red local." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5678,7 +5655,7 @@ msgstr "" "Compartir en grupo - accesible solo para las personas que estén en el grupo " "freedombox-share." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5686,15 +5663,15 @@ msgstr "" "Compartir en mi cuenta - todos los miembros del grupo freedombox-share " "disponen de un espacio privado propio." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Acceso a los elementos compartidos privados" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Sistema de archivos en red" @@ -5783,15 +5760,15 @@ msgstr "Nombre de compartición" msgid "Action" msgstr "Acción" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "Disco de sistema de FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Compartir en abierto" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Compartir con grupo" @@ -5817,7 +5794,7 @@ msgstr "Compartición desactivada." msgid "Error disabling share: {error_message}" msgstr "Error al desactivar compartición: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5825,7 +5802,7 @@ msgstr "" "Searx es un motor de búsqueda en Internet que respeta la privacidad. Recoge " "y muestra los resultados de múltiples buscadores." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5833,41 +5810,41 @@ msgstr "" "Searx se puede usar para evitar el rastreo y la creación de perfiles que " "realizan los buscadores. Por defecto no almacena cookies." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Buscar en la web" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Buscador web" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Búsqueda segura" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Seleccione la familia de filtros que se aplicarán por defecto a los " "resultados de su búsqueda." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Moderado" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Estricto" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Permitir acceso público" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Permitir que esta aplicación la use cualquiera que pueda acceder a ella." @@ -6048,7 +6025,7 @@ msgstr "Marcadores" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6058,7 +6035,7 @@ msgstr "" "tráfico en Internet. Se puede usar para eludir el filtrado o la censura de " "Internet." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6071,7 +6048,7 @@ msgstr "" "Los dispositivos locales pueden conectarse a este proxy y la información se " "enviará cifrada a través del servidor Shadowsocks." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6079,40 +6056,40 @@ msgstr "" "Para usar Shadowsocks una vez configurado debe indicar la URL del proxy en " "su dispositivo, navegador o aplicación como http://freedombox_address:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Proxy Socks5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Recomendado" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Servidor" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Nombre del servidor o dirección IP" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Número de puerto del servidor" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "Clave para cifrar los datos. Debe coincidir con la clave del servidor." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Método de cifrado. Debe coincidir con la configuración del servidor." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6121,15 +6098,15 @@ msgstr "" "Permite compartir a través de la web archivos y carpetas en su {box_name} " "con otras personas." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Compartir" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Nombre de la compartición" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6137,29 +6114,29 @@ msgstr "" "Una cadena alfa-numérica en minúsculas que identifica de forma unívoca la " "compartición. Ejemplo: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Ruta de acceso a la compartición" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" "Ruta de acceso en el disco de este servidor a la carpeta que pretende " "compartir." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Carpeta pública" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Dar acceso a los archivos de esta carpeta a quien tenga el enlace." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Grupos de usuarias/os que pueden leer los archivos compartidos:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6167,11 +6144,11 @@ msgstr "" "Los usuarios de los grupos seleccionados podrán leer los archivos " "compartidos." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Ya existe una compartición con este nombre." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" "Las carpetas compartidas deben ser públicas o estar compartidas con al menos " @@ -6210,19 +6187,19 @@ msgstr "Compartición añadida." msgid "Add Share" msgstr "Añadir compartición" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Compartición editada." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Editar compartición" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Compartición eliminada." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6232,7 +6209,7 @@ msgstr "" "btrfs. Éstas pueden emplearse para recuperar el sistema a un estado anterior " "correcto en caso de cambios no deseados." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6244,7 +6221,7 @@ msgstr "" "instantáneas más antiguas se eliminarán automáticamente según la siguiente " "configuración." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for las copias de seguridad ya que se almacenan en la " "misma partición. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Instantáneas" @@ -6359,7 +6336,7 @@ msgstr "Fecha" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Eliminar instantáneas" @@ -6412,58 +6389,58 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Restaurar a instantánea %(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "creada a mano" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "linea de tiempo" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "APT" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Gestionar instantáneas" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Instantánea creada." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Configuración de instantáneas actualizada" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Acción de error: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Las instantáneas seleccionadas fueron eliminadas" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" "La instantánea se está usando actualmente. Inténtelo de nuevo más tarde." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Sistema restaurado a la instantánea {number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Debe reiniciar el sistema para completar la restauración." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Restaurar a instantánea" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6475,7 +6452,7 @@ msgstr "" "de administración, copiar archivos o ejecutar otros servicios a través de " "esas conexiones." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Servidor de intérprete de órdenes seguro (SSH)" @@ -6513,14 +6490,6 @@ msgstr "Algoritmo" msgid "Fingerprint" msgstr "Huella digital" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "Acceso SSH con clave desactivado." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Acceso SSH con clave activado." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Inicio de sesión único" @@ -6533,7 +6502,7 @@ msgstr "Inicio de sesión" msgid "Logged out successfully." msgstr "Desconectado con éxito." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6544,106 +6513,106 @@ msgstr "" "{box_name}. Puede ver el medio de almacenamiento que está usando, montar y " "desmontar medios extraíbles, ampliar la partición raíz, etc." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Almacenamiento" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bytes" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Falló la operación." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Se ha cancelado la operación." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "El dispositivo ya se está desmontando." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "No se soporta esta operación por falta de un driver o herramienta." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "La operación agotó el tiempo." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "La operación podría activar un disco que está en estado de reposo." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Tratando de desmontar un dispositivo ocupado." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Ya se ha cancelado la operación." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "No tiene autorización para la operación solicitada." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "El dispositivo ya está montado." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "El dispositivo no está montado." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "La operación solicitada no está permitida." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "El dispositivo está ya montado por otro usuario." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Poco espacio en la partición del sistema: {percent_used}% usado, " "{free_space} libre." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Poco espacio en disco" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Fallo de disco inminente" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6652,39 +6621,39 @@ msgstr "" "El disco {id} informa que es probable que falle en breve. Copie los datos " "mientras pueda y reemplace el disco." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Nombre de carpeta no válido." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "La carpeta no existe." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "No es una carpeta." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "El usuario no tiene permiso de lectura en esta carpeta." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "El usuario no tiene permiso de escritura en esta carpeta." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Carpeta" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Subcarpeta (opcional)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Compartir" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Otra carpeta (especifique más abajo)" @@ -6721,7 +6690,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Ampliar partición raíz" @@ -6745,30 +6714,30 @@ msgstr "" "operación su partición raíz dispondrá de %(expandable_root_size)s espacio " "libre adicional." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Error al ampliar partición: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Partición ampliada con éxito." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "Ya puede desconectar {drive_vendor} {drive_model} con seguridad." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "El dispositivo ya se puede desconectar con seguridad." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Error al expulsar el dispositivo: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6780,7 +6749,7 @@ msgstr "" "modificación o borrado de archivos en uno de los dispositivos se replica " "automáticamente en todos los demás que también estén ejecutando Syncthing." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6799,20 +6768,20 @@ msgstr "" "interfaz web en {box_name} solo está disponible para quienes pertenezcan a " "los grupos \"admin\" o \"syncthing-access\"." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Administrar Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Sincronización de archivos" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6826,7 +6795,7 @@ msgstr "" "download/download-easy.html.en\">Navegador Tor para tener la mejor " "protección cuando navega por la red." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6835,40 +6804,40 @@ msgstr "" "Un puerto SOCKS de Tor está disponible para redes internas en su {box_name} " "en el puerto TCP 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Servicio Tor Onion" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Proxy Socks para Tor" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Puente de retransmisión Tor" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Puerto de servidor Tor disponible" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Transporte Obfs3 registrado" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Transporte Obfs4 registrado" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Acceso a URL {url} sobre tcp {kind} vía Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Confirmar uso de Tor en {url} sobre tcp {kind}" @@ -6989,13 +6958,13 @@ msgstr "Servicio Onion" msgid "Ports" msgstr "Puertos" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Ha habido un error en la configuración." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error updating app: {error}" msgid "Error configuring app: {error}" @@ -7059,7 +7028,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7069,7 +7038,7 @@ msgstr "" "publicar desde cualquier lugar, a la vez que mantiene un aspecto de " "aplicación de escritorio en la medida de lo posible." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7078,7 +7047,7 @@ msgstr "" "Cuando está activado, Tiny Tiny RSS estará disponible para cualquier persona perteneciente a un grupo de lector de feeds." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7086,11 +7055,11 @@ msgstr "" "Cuando emplee una aplicación de móvil o de escritorio para Tiny Tiny RSS, " "use la URL /tt-rss-app para conectar." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Lector de noticias" @@ -7098,13 +7067,13 @@ msgstr "Lector de noticias" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Bifurcación)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Buscar y aplicar las últimas actualizaciones del software y de seguridad." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7118,22 +7087,22 @@ msgstr "" "tiempo. Si se decide retrasar el reinicio del sistema, éste se hará de forma " "automática a las 02:00 h." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Actualización de software (Update)" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox actualizado" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "No se pudo iniciar la actualización de la distribución" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7144,11 +7113,11 @@ msgstr "" "libres. Si está habilitada, la actualización de la distribución se " "reintentará tras 24h ." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Iniciada la actualización de la distribución" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7329,46 +7298,46 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Actualización automática de distibución activada" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Error al configurar las actualizaciones desatendidas: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Actualizaciones automáticas activadas" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Actualizaciones automáticas desactivadas" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Actualización automática de distibución activada" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Actualización automática de distibución desactivada" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Proceso de actualización iniciado." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "No se ha podido iniciar la actualización." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Las actualizaciones funcionales frecuentes están activadas." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Distribution upgrade enabled" msgid "Starting distribution upgrade test." msgstr "Actualización automática de distibución activada" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7379,7 +7348,7 @@ msgstr "" "requieren que además la cuenta de usuario conste en un grupo para " "autorizarles a acceder." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7391,15 +7360,15 @@ msgstr "" "sólo los usuarios del grupo admin pueden cambiar configuraciones de " "apps o del sistema." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Usuarias/os y grupos" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Acceso a todos los servicios y configuraciones del sistema" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Comprobar la entrada LDAP \"{search_item}\"" @@ -7417,11 +7386,11 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "Obligatorio. Hasta 150 caracteres. Solo letras, números y @/./-/_ ." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Contraseña de autorización" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7429,11 +7398,11 @@ msgstr "" "Introduce la contraseña del usuario \"{user}\" para autorizar modificaciones " "en la cuenta." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Contraseña no válida." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7448,12 +7417,12 @@ msgstr "" "servicios, también podrán acceder al sistema por SSH con privilegios de " "administración (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Ha fallado la creación de usuaria/o LDAP: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Ha fallado añadir usuaria/o nuevo al grupo {group}: {error}" @@ -7472,41 +7441,41 @@ msgstr "" "de una clave. Puede introducir más de una clave, cada una en una línea. Las " "líneas en blanco y las que empiecen por # se ignorarán." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Ha fallado renombrar al o la usuaria LDAP." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Ha fallado la eliminación del o de la usuaria del grupo." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Ha fallado añadir al o la usuaria al grupo." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "No es posible configurar las claves SSH." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Ha fallado al cambiar el estado del usuario." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Ha fallado cambiar la clave del o de la usuaria LDAP." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Ha fallado añadir usuaria/o nueva/o al grupo admin: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Falló al restringir el acceso a la consola: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Creada cuenta de usuaria/o, ya está usted en el sistema" @@ -7523,12 +7492,12 @@ msgstr "Guardar clave de acceso" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Crear usuaria/o" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Eliminar usuaria/o" @@ -7569,13 +7538,19 @@ msgid "The following administrator accounts exist in the system." msgstr "La siguiente cuenta de administración existe en el sistema." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Si ya hay una cuenta usable con %(box_name)s sáltese este paso: Si no, " "elimine estas cuentas desde la línea de órdenes y refresque la página para " @@ -7584,7 +7559,7 @@ msgstr "" "la línea de órdenes." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Usuarias/os" @@ -7617,34 +7592,34 @@ msgstr "" msgid "Save Changes" msgstr "Guardar cambios" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Se ha creado el o la usuaria %(username)s." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "El o la usuaria %(username)s se ha actualizado." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Editar usuario" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "El o la usuaria {user} se ha eliminado." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Ha fallado la eliminación del o de la usuaria LDAP." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Cambiar clave de acceso" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Clave de acceso cambiada con éxito." @@ -7981,7 +7956,7 @@ msgstr "Eliminar conexión al servidor" msgid "Server deleted." msgstr "Servidor eliminado." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7995,7 +7970,7 @@ msgstr "" "apariencia mediante temas. Tanto el interfaz de administración como las " "páginas web producidas son adecuados para dispositivos móviles." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8009,7 +7984,7 @@ msgstr "" "en el interfaz de administrador para tener mejores URLs de acceso a tus " "páginas y artículos." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8020,7 +7995,7 @@ msgstr "" "href=\"/wordpress/wp-admin/\">página de administración para acceder a " "ella en el futuro." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8030,12 +8005,12 @@ msgstr "" "de administración una actualización de la base de datos. Se pueden instalar " "y actualizar plugins y temas adicionales asumiendo los riesgos." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Sitio web y Blog" @@ -8052,7 +8027,7 @@ msgstr "" "WordPress o blog a los administradores. Habilítalo solo después de ejecutar " "la configuración inicial de WordPress." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8074,7 +8049,7 @@ msgstr "" "de mapa y calendario. Se pueden compartir fotos sueltas con otras personas " "enviándoles un enlace directo." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8085,11 +8060,11 @@ msgstr "" "Para añadir más usuarios hay que crear cuentas con el mismo nombre tanto en " "Zoph como en {box_name} ." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Organizador de fotografías" @@ -8141,102 +8116,96 @@ msgstr "Esperando a empezar: {name}" msgid "Finished: {name}" msgstr "Terminó: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "El paquete {expression} no está disponible para instalar" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "El paquete {package_name} es la última versión ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Error al respaldar" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "instalando" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "descargando" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "cambio de medio" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "archivo de configuración: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Tiempo máximo esperando al administrador de paquetes" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Instalando app" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Actualizando app" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Error al instalar la app: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Error al actualizar la aplicación: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Error al instalar la app: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Error al actualizar la app: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "App instalada." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "App actualizada" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Instalando app" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing app: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Error al instalar la app: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing app: {error}" msgid "Error uninstalling app: {error}" msgstr "Error al instalar la app: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "App installed." msgid "App uninstalled." msgstr "App instalada." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Actualizando los paquetes de la app" @@ -8296,53 +8265,54 @@ msgstr "Instalación" msgid "Service %(service_name)s is not running." msgstr "El servidor %(service_name)s no se está ejecutando." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Funcionalidad central e interfaz web para %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Inicio" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Principal" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Aplicaciones" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Aplicaciones" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Sistema" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Sistema" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Cambiar clave de acceso" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Apagar" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Cerrar sesión" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Seleccionar idioma" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Iniciar sesión" @@ -8631,6 +8601,77 @@ msgstr "" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Activar DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Activar Extensiones de Seguridad del Sistema de Nombre de Dominios" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "El servicio firewall no se está ejecutando. Por favor actívelo. El " +#~ "firewall viene activado por defecto en su %(box_name)s. En cualquier " +#~ "sistema basado en Debian (como %(box_name)s) puede activarlo con 'service " +#~ "firewalld start' o si su sistema emplea systemd 'systemctl start " +#~ "firewalld'." + +#~ msgid "Migrate to ECC" +#~ msgstr "Migrar a crioptografía ECC (basada en curvas elípticas)" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Actualmemte tu instalación OpenVPN está usando RSA. Cambiar a " +#~ "Criptografía de Curva Elíptica (ECC) mejora la velocidad y seguridad al " +#~ "establecer conexiones. Esta operación es irreversible. En la mayoría de " +#~ "computadores monoplaca debería tardar escasos minutos." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Todas las instalaciones nuevas de OpenVPN sobre %(box_name)s usarán ECC " +#~ "de serie. Recomendamos migrar cuanto antes." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Aviso: Esta operación invalidará los perfiles de cliente " +#~ "existentes. Todos los usuarios de OpenVPN en %(box_name)s tienen que " +#~ "descargar sus perfiles nuevos. Para conectar con este servidor tendrán " +#~ "que usar clientes OpenVPN compatibles con ECC." + +#~ msgid "Migrate" +#~ msgstr "Migrar" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "Acceso SSH con clave desactivado." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Acceso SSH con clave activado." + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Error al respaldar" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Funcionalidad central e interfaz web para %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Conexiones de red" diff --git a/plinth/locale/fa/LC_MESSAGES/django.po b/plinth/locale/fa/LC_MESSAGES/django.po index 89ac45c0a..554f9ef7e 100644 --- a/plinth/locale/fa/LC_MESSAGES/django.po +++ b/plinth/locale/fa/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Persian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Create Connection" msgid "Name of the new library" msgstr "ساختن اتصال" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1126,22 +1117,22 @@ msgstr "" msgid "Delete library %(library)s" msgstr "سایت %(site)s را پاک کنید" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 #, fuzzy #| msgid "Error occurred while publishing key." msgid "An error occurred while creating the library." msgstr "هنگام انتشار کلید خطایی رخ داد." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} پاک شد." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "نشد که {name} پاک شود: {error}" @@ -1181,25 +1172,25 @@ msgstr "" msgid "Server Administration" msgstr "حساب مدیر" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "پیکربندی عمومی" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 #, fuzzy msgid "Configure" msgstr "پیکربندی" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1307,49 +1298,49 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "خطا در هنگام تنظیم نام میزبان: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "نام میزبان تنظیم شد" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "خطا در هنگام تنظیم نام دامنه: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "نام دامنه تنظیم شد" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, fuzzy, python-brace-format #| msgid "Error setting hostname: {exception}" msgid "Error setting webserver home page: {exception}" msgstr "خطا در هنگام تنظیم نام میزبان: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, fuzzy, python-brace-format #| msgid "Error setting domain name: {exception}" msgid "Error changing advanced mode: {exception}" msgstr "خطا در هنگام تنظیم نام دامنه: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1357,7 +1348,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as یا سرویس رایگان به‌روزرسانی نشانی را در freedns.afraid.org به کار ببرید." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 #, fuzzy msgid "Dynamic DNS Client" msgstr "برنامهٔ DNS متغیر (Dynamic DNS Client)" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 #, fuzzy #| msgid "Domain Name" msgid "Dynamic Domain Name" @@ -1779,7 +1770,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1847,13 +1838,13 @@ msgstr "پاک‌کردن اتصال" msgid "Already up-to-date" msgstr "آخرین به‌روزرسانی" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 #, fuzzy #| msgid "Web Server" msgid "Chat Server" @@ -1985,14 +1976,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2000,7 +1991,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2010,13 +2001,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2159,7 +2150,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2170,7 +2161,7 @@ msgstr "" "خروجی شبکه را در {box_name} شما کنترل می‌کند. فعال نگه‌داشتن فایروال و تنظیم " "درست آن خطر تهدیدهای امنیتی از طرف اینترنت را کم می‌کند." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "فایروال" @@ -2190,52 +2181,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"برنامهٔ فایروال در حال اجرا نیست. لطفاً آن را اجرا کنید. فایروال به طور پیش‌فرض " -"در %(box_name)s روشن است. روش روشن‌کردن آن در سیستم‌های برپایهٔ Debian (مانند " -"%(box_name)s) با فرمان 'service firewalld start' و در سیستم‌های دارای systemd " -"با فرمان 'systemctl start firewalld' است." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "سرویس/پورت" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "فعال" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "غیرفعال" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "مجاز" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "مجاز (فقط داخلی)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "مجاز (فقط خارجی)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "مسدود" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2244,13 +2222,13 @@ msgstr "" "کارکرد فایروال خودکار است. وقتی که یک سرویس را فعال کنید آن سرویس در فایروال " "هم مجاز می‌شود و وقتی آن را غیرفعال کنید در فایروال هم مسدود می‌شود." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2297,7 +2275,7 @@ msgstr "آغاز راه‌اندازی" msgid "Setup Complete" msgstr "راه‌اندازی کامل شد" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2308,83 +2286,83 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository URL." msgstr "نام میزبان معتبر نیست" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "نام میزبان معتبر نیست" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create Connection" msgid "Private repository" msgstr "ساختن اتصال" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Create Connection" msgid "Name of the repository" msgstr "ساختن اتصال" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default" msgid "Default branch" msgstr "پیش‌فرض" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2439,21 +2417,21 @@ msgstr "پاک‌کردن ویکی یا وبلاگ %(name)s" msgid "Delete this repository permanently?" msgstr "اتصال %(name)s را برای همیشه پاک می‌کنید؟" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 #, fuzzy #| msgid "Error occurred while publishing key." msgid "An error occurred while creating the repository." msgstr "هنگام انتشار کلید خطایی رخ داد." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Create Connection" msgid "Edit repository" @@ -2788,7 +2766,7 @@ msgstr "دربارهٔ {box_name}" msgid "{box_name} Manual" msgstr "کتاب راهنمای {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2796,7 +2774,7 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 #, fuzzy #| msgid "" #| "For more information about the %(box_name)s project, see the ویکی %(box_name)s را ببینید." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy msgid "Manage I2P application" msgstr "فعال‌سازی برنامه" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 #, fuzzy msgid "Anonymity Network" msgstr "رفتن به تنظیمات شبکه" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2865,7 +2843,7 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 #, fuzzy #| msgid "" #| "ikiwiki is a simple wiki and blog application. It supports several " @@ -2882,7 +2860,7 @@ msgstr "" "پشتیبانی می‌کند. اگر این برنامه فعال باشد، وبلاگ‌ها و ویکی‌ها از نشانی /ikiwiki قابل دسترس خواهند بود." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2891,17 +2869,17 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 #, fuzzy #| msgid "Manage Wikis and Blogs" msgid "Wiki and Blog" msgstr "مدیریت ویکی‌ها و وبلاگ‌ها" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 #, fuzzy msgid "View and edit wiki applications" msgstr "سرویس‌ها و برنامه‌ها" @@ -2958,43 +2936,43 @@ msgstr "" "این کار همهٔ نوشته‌ها، صفحه‌ها، نظرها، و تاریخچهٔ آن‌ها را حذف می‌کند. آیا به " "پاک‌کردن ویکی یا وبلاگ ادامه می‌دهید؟" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "ویکی {name} ساخته شد." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "ساختن ویکی شکست خورد: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "وبلاگ {name} ساخته شد." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "ساختن وبلاگ شکست خورد: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, fuzzy, python-brace-format #| msgid "{name} deleted." msgid "{title} deleted." msgstr "{name} پاک شد." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, fuzzy, python-brace-format #| msgid "Could not delete {name}: {error}" msgid "Could not delete {title}: {error}" msgstr "نشد که {name} پاک شود: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3002,11 +2980,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 #, fuzzy #| msgid "Web Server" msgid "Gobby Server" @@ -3054,7 +3032,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -3072,7 +3050,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "A digital certficate allows users of a web service to verify the identity " @@ -3093,7 +3071,7 @@ msgstr "" "برای این کار {box_name} به Let's Encrypt (که یک مرجع صدور گواهی دیجیتال است) " "اثبات می‌کند که مالک دامنه است." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 #, fuzzy #| msgid "" #| "Let's Encrypt is a free, automated, and open certificate authority, run " @@ -3113,19 +3091,19 @@ msgstr "" "\"https://letsencrypt.org/repository/\">قرارداد اشتراک Let's Encrypt " "بخوانید و آن را بپذیرید." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 #, fuzzy #| msgid "Certificates (Let's Encrypt)" msgid "Let's Encrypt" msgstr "گواهی دیجیتال (Let's Encrypt)" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 #, fuzzy #| msgid "Certificate Status" msgid "Certificates" msgstr "وضعیت گواهی دیجیتال" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3194,7 +3172,7 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, fuzzy, python-brace-format #| msgid "Certificate successfully revoked for domain {domain}" msgid "" @@ -3202,36 +3180,36 @@ msgid "" "moments to take effect." msgstr "گواهی دامنهٔ {domain} با موفقیت باطل شد" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "باطل‌کردن گواهی دامنهٔ {domain} شکست خورد: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "گواهی دیجیتال برای دامنهٔ {domain} با موفقیت گرفته شد" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "گرفتن گواهی برای دامنهٔ {domain} شکست خورد: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, fuzzy, python-brace-format #| msgid "Certificate successfully revoked for domain {domain}" msgid "Certificate successfully deleted for domain {domain}" msgstr "گواهی دامنهٔ {domain} با موفقیت باطل شد" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, fuzzy, python-brace-format #| msgid "Failed to revoke certificate for domain {domain}: {error}" msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "باطل‌کردن گواهی دامنهٔ {domain} شکست خورد: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3241,14 +3219,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -3330,7 +3308,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3338,7 +3316,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3347,18 +3325,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3437,42 +3415,42 @@ msgstr "رمز" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 #, fuzzy msgid "Public registrations enabled" msgstr "برنامه نصب شد." -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 #, fuzzy msgid "Public registrations disabled" msgstr "برنامه نصب شد." -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy msgid "Private mode disabled" msgstr "برنامه نصب شد." -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "نام دامنه تنظیم شد" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "نام دامنه تنظیم شد" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, fuzzy, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3485,11 +3463,11 @@ msgstr "" "برای اتصال به سرور به یک برنامهٔ ماین‌تست نیاز است." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 #, fuzzy msgid "Block Sandbox" msgstr "بازی مکعب‌ها (Minetest)" @@ -3540,7 +3518,7 @@ msgstr "" msgid "Address" msgstr "نشانی" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3715,19 +3693,19 @@ msgstr "پوستهٔ ایمن" msgid "Services" msgstr "سرویس" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "شبکه‌ها" @@ -4105,7 +4083,7 @@ msgstr "ویرایش اتصال" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "ویرایش" @@ -4210,7 +4188,7 @@ msgstr "آی‌پی ن۴" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "روش" @@ -4226,7 +4204,7 @@ msgstr "دی‌ان‌اس" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "پیش‌فرض" @@ -4239,7 +4217,7 @@ msgid "This connection is not active." msgstr "این اتصال فعال نیست." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "امنیت" @@ -4837,7 +4815,7 @@ msgstr "اتصال {name} پاک شد." msgid "Failed to delete connection: Connection not found." msgstr "پاک‌کردن اتصال شکست خورد: اتصال پیدا نشد." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4848,24 +4826,24 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection Type" msgid "Connect to VPN services" msgstr "نوع اتصال" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 #, fuzzy #| msgid "Open" msgid "OpenVPN" msgstr "باز" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4875,63 +4853,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -#, fuzzy -#| msgid "Mode" -msgid "Migrate" -msgstr "حالت" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4940,33 +4884,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4975,89 +4919,89 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 #, fuzzy #| msgid "Available Domains" msgid "PageKite Domain" msgstr "دامنه‌های موجود" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -5091,29 +5035,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5155,8 +5099,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -5198,6 +5142,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5229,7 +5204,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5240,7 +5215,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -5260,7 +5235,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5270,19 +5245,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5343,7 +5318,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 #, fuzzy #| msgid "Configuration updated" msgid "Access rights configuration updated" @@ -5413,7 +5388,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5426,13 +5401,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5441,31 +5416,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Interface" msgid "Network File Storage" @@ -5553,18 +5528,18 @@ msgstr "مشترک" msgid "Action" msgstr "کنش‌ها" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy msgid "FreedomBox OS disk" msgstr "FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 #, fuzzy #| msgid "Shared" msgid "Open Share" msgstr "مشترک" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 #, fuzzy #| msgid "Shared" msgid "Group Share" @@ -5600,55 +5575,55 @@ msgstr "مشترک" msgid "Error disabling share: {error_message}" msgstr "خطا هنگام نصب برنامه: {error}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 #, fuzzy #| msgid "Web Server" msgid "Web Search" msgstr "سرور وب" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 #, fuzzy #| msgid "Mode" msgid "Moderate" msgstr "حالت" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5814,14 +5789,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5830,103 +5805,103 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 #, fuzzy #| msgid "Service" msgid "Server" msgstr "سرویس" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 #, fuzzy #| msgid "Shared" msgid "Sharing" msgstr "مشترک" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 #, fuzzy #| msgid "Publish Key" msgid "Public share" msgstr "انتشار کلید" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5969,32 +5944,32 @@ msgstr "مشترک" msgid "Add Share" msgstr "مشترک" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 #, fuzzy #| msgid "Shared" msgid "Share edited." msgstr "مشترک" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 #, fuzzy #| msgid "Shared" msgid "Edit Share" msgstr "مشترک" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 #, fuzzy #| msgid "{name} deleted." msgid "Share deleted." msgstr "{name} پاک شد." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6002,14 +5977,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 #, fuzzy #| msgid "Delete %(name)s" msgid "Storage Snapshots" @@ -6115,7 +6090,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 #, fuzzy #| msgid "Delete %(name)s" msgid "Delete Snapshots" @@ -6165,65 +6140,65 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Last update" msgid "manually created" msgstr "آخرین به‌روزرسانی" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 #, fuzzy #| msgid "Delete %(name)s" msgid "Manage Snapshots" msgstr "پاک‌کردن %(name)s" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 #, fuzzy #| msgid "Configuration updated" msgid "Storage snapshots configuration updated" msgstr "پیکربندی به‌روز شد" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 #, fuzzy #| msgid "Delete %(name)s" msgid "Deleted selected snapshots" msgstr "پاک‌کردن %(name)s" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6231,7 +6206,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -6270,14 +6245,6 @@ msgstr "" msgid "Fingerprint" msgstr "اثر انگشت SSH" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6292,7 +6259,7 @@ msgstr "" msgid "Logged out successfully." msgstr "پارتیشن با موفقیت بزرگ شد." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6300,153 +6267,153 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, fuzzy, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size} بایت" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, fuzzy, python-brace-format #| msgid "{disk_size} KiB" msgid "{disk_size:.1f} KiB" msgstr "{disk_size} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, fuzzy, python-brace-format #| msgid "{disk_size} MiB" msgid "{disk_size:.1f} MiB" msgstr "{disk_size} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, fuzzy, python-brace-format #| msgid "{disk_size} GiB" msgid "{disk_size:.1f} GiB" msgstr "{disk_size} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, fuzzy, python-brace-format #| msgid "{disk_size} TiB" msgid "{disk_size:.1f} TiB" msgstr "{disk_size} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 #, fuzzy #| msgid "The requested domain is already registered." msgid "The device is already mounted." msgstr "دامنهٔ درخواستی از قبل ثبت شده است." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "نام میزبان معتبر نیست" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 #, fuzzy #| msgid "Shared" msgid "Share" msgstr "مشترک" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6486,7 +6453,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "بزرگ‌کردن پارتیشن ریشه" @@ -6507,30 +6474,30 @@ msgstr "" "%(expandable_root_size)s فضای خالی در اختیار پارتیشن ریشهٔ شما قرار خواهد " "گرفت." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "خطا در هنگام بزرگ‌کردن پارتیشن: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "پارتیشن با موفقیت بزرگ شد." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6538,7 +6505,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6550,20 +6517,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6572,47 +6539,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6712,13 +6679,13 @@ msgstr "سرویس" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "Current Network Configuration" msgid "Updating configuration" msgstr "پیکربندی فعلی شبکه" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6771,31 +6738,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6803,12 +6770,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6816,8 +6783,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -6825,28 +6792,28 @@ msgstr "" msgid "Software Update" msgstr "{name} پاک شد." -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy msgid "FreedomBox Updated" msgstr "FreedomBox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy msgid "Distribution update started" msgstr "برنامه نصب شد." -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7005,53 +6972,53 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "برنامه نصب شد." -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy msgid "Distribution upgrade disabled" msgstr "برنامه نصب شد." -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy msgid "Starting distribution upgrade test." msgstr "برنامه نصب شد." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7059,15 +7026,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -7087,25 +7054,25 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Account" msgid "Authorization Password" msgstr "حساب مدیر" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "رمز را نشان بده" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7114,13 +7081,13 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, fuzzy, python-brace-format #| msgid "Creating LDAP user failed." msgid "Creating LDAP user failed: {error}" msgstr "ساختن کاربر LDAP شکست خورد." -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, fuzzy, python-brace-format #| msgid "Failed to add new user to admin group." msgid "Failed to add new user to {group} group: {error}" @@ -7137,45 +7104,45 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add new user to admin group." msgid "Failed to change user status." msgstr "افزودن کاربر به گروه مدیران شکست خورد." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, fuzzy, python-brace-format #| msgid "Failed to add new user to admin group." msgid "Failed to add new user to admin group: {error}" msgstr "افزودن کاربر به گروه مدیران شکست خورد." -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, fuzzy, python-brace-format #| msgid "Failed to obtain certificate for domain {domain}: {error}" msgid "Failed to restrict console access: {error}" msgstr "گرفتن گواهی برای دامنهٔ {domain} شکست خورد: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "حساب کاربری ساخته شد، شما الان وارد سیستم هستید" @@ -7192,12 +7159,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -7242,17 +7209,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -7284,34 +7251,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7660,7 +7627,7 @@ msgstr "پاک‌کردن اتصال" msgid "Server deleted." msgstr "{name} پاک شد." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7669,7 +7636,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7678,28 +7645,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "نشانی" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Manage Wikis and Blogs" msgid "Website and Blog" @@ -7717,7 +7684,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7730,7 +7697,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7738,11 +7705,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7794,107 +7761,101 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "خظا هنگام پشتیبان‌گیری" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format msgid "Error installing app: {string} {details}" msgstr "خطا هنگام نصب برنامه: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format msgid "Error updating app: {string} {details}" msgstr "خطا هنگام نصب برنامه: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "خطا هنگام نصب برنامه: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "خطا هنگام نصب برنامه: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy msgid "App installed." msgstr "برنامه نصب شد." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "آخرین به‌روزرسانی" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "خطا هنگام نصب برنامه: {error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "خطا هنگام نصب برنامه: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "خطا هنگام نصب برنامه: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy msgid "App uninstalled." msgstr "برنامه نصب شد." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7945,57 +7906,58 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 #, fuzzy msgid " Apps" msgstr "برنامه‌ها" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 #, fuzzy msgid "Apps" msgstr "برنامه‌ها" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 #, fuzzy #| msgid "Language" msgid "Select language" msgstr "زبان" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -8265,6 +8227,33 @@ msgstr "" msgid "Gujarati" msgstr "" +#, fuzzy +#~| msgid "Enable Dynamic DNS" +#~ msgid "Enable DNSSEC" +#~ msgstr "فعال‌سازی DNS متغیر" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "برنامهٔ فایروال در حال اجرا نیست. لطفاً آن را اجرا کنید. فایروال به طور " +#~ "پیش‌فرض در %(box_name)s روشن است. روش روشن‌کردن آن در سیستم‌های برپایهٔ " +#~ "Debian (مانند %(box_name)s) با فرمان 'service firewalld start' و در " +#~ "سیستم‌های دارای systemd با فرمان 'systemctl start firewalld' است." + +#, fuzzy +#~| msgid "Mode" +#~ msgid "Migrate" +#~ msgstr "حالت" + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "خظا هنگام پشتیبان‌گیری" + #~ msgid "Network Connections" #~ msgstr "اتصال‌های شبکه" diff --git a/plinth/locale/fake/LC_MESSAGES/django.po b/plinth/locale/fake/LC_MESSAGES/django.po index dfff9cc3a..faa5e7dcb 100644 --- a/plinth/locale/fake/LC_MESSAGES/django.po +++ b/plinth/locale/fake/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Plinth 0.6\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2016-01-31 22:24+0530\n" "Last-Translator: Sunil Mohan Adapa \n" "Language-Team: Plinth Developers calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Create User" msgid "Name of the new library" msgstr "CREATE USER" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 #, fuzzy #| msgid "This service already exists" msgid "A library with this name already exists." @@ -1170,24 +1161,24 @@ msgstr "" msgid "Delete library %(library)s" msgstr "DELETE SITE %(site)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "packages not found" msgid "Library created." msgstr "PACKAGES NOT FOUND" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 #, fuzzy #| msgid "An error occurred during configuration." msgid "An error occurred while creating the library." msgstr "AN ERROR OCCURRED DURING CONFIGURATION." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} DELETED." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "COULD NOT DELETE {name}: {error}" @@ -1232,24 +1223,24 @@ msgstr "" msgid "Server Administration" msgstr "SERVER DOMAIN" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "GENERAL CONFIGURATION" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "CONFIGURE" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1361,49 +1352,49 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "ERROR SETTING HOSTNAME: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "HOSTNAME SET" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "ERROR SETTING DOMAIN NAME: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "DOMAIN NAME SET" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, fuzzy, python-brace-format #| msgid "Error setting hostname: {exception}" msgid "Error setting webserver home page: {exception}" msgstr "ERROR SETTING HOSTNAME: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, fuzzy, python-brace-format #| msgid "Error setting domain name: {exception}" msgid "Error changing advanced mode: {exception}" msgstr "ERROR SETTING DOMAIN NAME: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1411,7 +1402,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as /DELUGE PATH ON THE WEB SERVER. THE DEFAULT PASSWORD IS 'DELUGE', BUT " "YOU SHOULD LOG IN AND CHANGE IT IMMEDIATELY AFTER ENABLING THIS SERVICE." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 #, fuzzy #| msgid "Enable Deluge" msgid "Deluge" msgstr "ENABLE DELUGE" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 #, fuzzy #| msgid "BitTorrent Web Client (Deluge)" @@ -1647,7 +1638,7 @@ msgstr "RESULT" msgid "Diagnostic Test" msgstr "DIAGNOSTIC TEST" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, fuzzy, python-brace-format #| msgid "" #| "If your internet provider changes your IP address periodic (i.e. every " @@ -1663,7 +1654,7 @@ msgstr "" "IT MAY BE HARD FOR OTHERS TO FIND YOU IN THE WEB. AND FOR THIS REASON NOBODY " "MAY FIND THE SERVICES WHICH ARE PROVIDED BY %(box_name)s, SUCH AS OWNCLOUD." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 #, fuzzy #| msgid "" #| "The solution is to assign a DNS name to your IP address and update the " @@ -1689,7 +1680,7 @@ msgstr "" "THE SERVER WILL ASSIGN YOUR DNS NAME WITH THE NEW IP AND IF SOMEONE FROM THE " "INTERNET ASKS FOR YOUR DNS NAME HE WILL GET YOUR CURRENT IP ANSWERED." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 #, fuzzy #| msgid "" #| "If you are looking for a free dynamic DNS account, you may find a free " @@ -1709,11 +1700,11 @@ msgstr "" "BASED SERVICES ON " "FREEDNS.AFRAID.ORG." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "DYNAMIC DNS CLIENT" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 #, fuzzy #| msgid "Domain Name" msgid "Dynamic Domain Name" @@ -1863,7 +1854,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1932,7 +1923,7 @@ msgstr "DELETE CONNECTION" msgid "Already up-to-date" msgstr "LAST UPDATE" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1940,7 +1931,7 @@ msgstr "" "XMPP IS AN OPEN AND STANDARDIZED COMMUNICATION PROTOCOL. HERE YOU CAN RUN " "AND CONFIGURE YOUR XMPP SERVER, CALLED EJABBERD." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, fuzzy, python-brace-format #| msgid "" #| "To actually communicate, you can use the web client " @@ -1956,19 +1947,19 @@ msgstr "" "ANY OTHER XMPP CLIENT." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 #, fuzzy #| msgid "Web Server" msgid "Chat Server" @@ -2082,14 +2073,14 @@ msgstr "" "LIKE USERNAME@%(domainname)s. YOU CAN SETUP YOUR DOMAIN ON THE SYSTEM " "CONFIGURE PAGE." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2097,7 +2088,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2107,13 +2098,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2258,7 +2249,7 @@ msgstr "PORT" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, fuzzy, python-brace-format #| msgid "" #| "Firewall is a security system that controls the incoming and outgoing " @@ -2273,7 +2264,7 @@ msgstr "" "NETWORK TRAFFIC ON YOUR %(box_name)s. KEEPING A FIREWALL ENABLED AND " "PROPERLY CONFIGURED REDUCES RISK OF SECURITY THREAT FROM THE INTERNET." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "FIREWALL" @@ -2295,52 +2286,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"FIREWALL DAEMON IS NOT RUNNING. PLEASE RUN IT. FIREWALL COMES ENABLED BY " -"DEFAULT ON %(box_name)s. ON ANY DEBIAN BASED SYSTEM (SUCH AS %(box_name)s) " -"YOU MAY RUN IT USING THE COMMAND 'SERVICE FIREWALLD START' OR IN CASE OF A " -"SYSTEM WITH SYSTEMD 'SYSTEMCTL START FIREWALLD'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "SERVICE/PORT" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "ENABLED" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "DISABLED" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "PERMITTED" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "PERMITTED (INTERNAL ONLY)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "PERMITTED (EXTERNAL ONLY)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "BLOCKED" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2350,13 +2328,13 @@ msgstr "" "ALSO PERMITTED IN THE FIREWALL AND WHEN YOU DISABLE A SERVICE IT IS ALSO " "DISABLED IN THE FIREWALL." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2404,7 +2382,7 @@ msgstr "START SETUP" msgid "Setup Complete" msgstr "SETUP COMPLETE" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2415,87 +2393,87 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository URL." msgstr "INVALID HOSTNAME" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "INVALID HOSTNAME" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 #, fuzzy #| msgid "packages not found" msgid "Repository's owner name" msgstr "PACKAGES NOT FOUND" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create User" msgid "Private repository" msgstr "CREATE USER" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 #, fuzzy #| msgid "This service already exists" msgid "A repository with this name already exists." msgstr "THIS SERVICE ALREADY EXISTS" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Create User" msgid "Name of the repository" msgstr "CREATE USER" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default" msgid "Default branch" msgstr "DEFAULT" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2550,25 +2528,25 @@ msgstr "DELETE WIKI OR BLOG %(name)s" msgid "Delete this repository permanently?" msgstr "DELETE USER PERMANENTLY?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 #, fuzzy #| msgid "packages not found" msgid "Repository created." msgstr "PACKAGES NOT FOUND" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 #, fuzzy #| msgid "An error occurred during configuration." msgid "An error occurred while creating the repository." msgstr "AN ERROR OCCURRED DURING CONFIGURATION." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 #, fuzzy #| msgid "packages not found" msgid "Repository edited." msgstr "PACKAGES NOT FOUND" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Create User" msgid "Edit repository" @@ -2914,7 +2892,7 @@ msgstr "ABOUT {box_name}" msgid "{box_name} Manual" msgstr "{box_name} MANUAL" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2922,7 +2900,7 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 #, fuzzy #| msgid "" #| "For more information about the %(box_name)s project, see the %(box_name)s WIKI." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy #| msgid "Applications" msgid "Manage I2P application" msgstr "APPLICATIONS" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 #, fuzzy #| msgid "Tor Anonymity Network" msgid "Anonymity Network" msgstr "TOR ANONYMITY NETWORK" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 #, fuzzy #| msgid "Privoxy Web Proxy" msgid "I2P Proxy" @@ -2995,14 +2973,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -3011,17 +2989,17 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 #, fuzzy #| msgid "wiki" msgid "ikiwiki" msgstr "WIKI" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "WIKI AND BLOG" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 #, fuzzy #| msgid "Services and Applications" msgid "View and edit wiki applications" @@ -3079,43 +3057,43 @@ msgstr "" "THIS ACTION WILL REMOVE ALL THE POSTS, PAGES AND COMMENTS INCLUDING REVISION " "HISTORY. DELETE THIS WIKI OR BLOG PERMANENTLY?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "CREATED WIKI {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "COULD NOT CREATE WIKI: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "CREATED BLOG {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "COULD NOT CREATE BLOG: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, fuzzy, python-brace-format #| msgid "{name} deleted." msgid "{title} deleted." msgstr "{name} DELETED." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, fuzzy, python-brace-format #| msgid "Could not delete {name}: {error}" msgid "Could not delete {title}: {error}" msgstr "COULD NOT DELETE {name}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3123,11 +3101,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 #, fuzzy #| msgid "Web Server" msgid "Gobby Server" @@ -3175,7 +3153,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -3195,7 +3173,7 @@ msgstr "" msgid "Chat Client" msgstr "IRC CLIENT (QUASSEL)" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "A digital certficate allows users of a web service to verify the identity " @@ -3216,7 +3194,7 @@ msgstr "" "DOMAIN. IT DOES SO BY PROVING ITSELF TO BE THE OWNER OF A DOMAIN TO LET'S " "ENCRYPT, A CERTFICATE AUTHORITY (CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 #, fuzzy #| msgid "" #| "Let's Encrypt is a free, automated, and open certificate authority, run " @@ -3235,19 +3213,19 @@ msgstr "" "READ AND AGREE WITH THE LET'S ENCRYPT SUBSCRIBER AGREEMENT BEFORE USING THIS SERVICE." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 #, fuzzy #| msgid "Certificates (Let's Encrypt)" msgid "Let's Encrypt" msgstr "CERTIFICATES (LET'S ENCRYPT)" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 #, fuzzy #| msgid "Certificate Status" msgid "Certificates" msgstr "CERTIFICATE STATUS" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3318,7 +3296,7 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, fuzzy, python-brace-format #| msgid "Certificate successfully revoked for domain {domain}" msgid "" @@ -3326,36 +3304,36 @@ msgid "" "moments to take effect." msgstr "CERTIFICATE SUCCESSFULLY REVOKED FOR DOMAIN {domain}" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "FAILED TO REVOKE CERTIFICATE FOR DOMAIN {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "CERTIFICATE SUCCESSFULLY OBTAINED FOR DOMAIN {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "FAILED TO OBTAIN CERTIFICATE FOR DOMAIN {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, fuzzy, python-brace-format #| msgid "Certificate successfully revoked for domain {domain}" msgid "Certificate successfully deleted for domain {domain}" msgstr "CERTIFICATE SUCCESSFULLY REVOKED FOR DOMAIN {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, fuzzy, python-brace-format #| msgid "Failed to revoke certificate for domain {domain}: {error}" msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "FAILED TO REVOKE CERTIFICATE FOR DOMAIN {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3365,14 +3343,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 #, fuzzy #| msgid "Chat Server (XMPP)" msgid "Matrix Synapse" @@ -3464,7 +3442,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3472,7 +3450,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3481,18 +3459,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3573,49 +3551,49 @@ msgstr "PASSWORD" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 #, fuzzy #| msgid "Applications" msgid "Public registrations enabled" msgstr "APPLICATIONS" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 #, fuzzy #| msgid "Applications" msgid "Public registrations disabled" msgstr "APPLICATIONS" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 #, fuzzy #| msgid "PageKite enabled" msgid "Private mode enabled" msgstr "PAGEKITE ENABLED" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy #| msgid "PageKite disabled" msgid "Private mode disabled" msgstr "PAGEKITE DISABLED" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 #, fuzzy #| msgid "Setting unchanged" msgid "Default skin changed" msgstr "SETTING UNCHANGED" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "DOMAIN NAME SET" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "DOMAIN NAME SET" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3624,11 +3602,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 #, fuzzy #| msgid "Blocked" msgid "Block Sandbox" @@ -3681,7 +3659,7 @@ msgstr "" msgid "Address" msgstr "ADDRESS" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3866,19 +3844,19 @@ msgstr "SECURE SHELL (SSH)" msgid "Services" msgstr "SERVICE" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "NETWORKS" @@ -4259,7 +4237,7 @@ msgstr "EDIT CONNECTION" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "EDIT" @@ -4364,7 +4342,7 @@ msgstr "IPV4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "METHOD" @@ -4380,7 +4358,7 @@ msgstr "DNS SERVER" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "DEFAULT" @@ -4393,7 +4371,7 @@ msgid "This connection is not active." msgstr "THIS CONNECTION IS NOT ACTIVE." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "SECURITY" @@ -4991,7 +4969,7 @@ msgstr "CONNECTION {name} DELETED." msgid "Failed to delete connection: Connection not found." msgstr "FAILED TO DELETE CONNECTION: CONNECTION NOT FOUND." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, fuzzy, python-brace-format #| msgid "" #| "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -5015,26 +4993,26 @@ msgstr "" "YOU CAN ALSO ACCESS THE REST OF THE INTERNET VIA %(box_name)s FOR ADDED " "SECURITY AND ANONYMITY." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection Type" msgid "Connect to VPN services" msgstr "CONNECTION TYPE" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 #, fuzzy #| msgid "OpenVPN" msgid "OpenVPN" msgstr "OPENVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 #, fuzzy #| msgid "Virtual Private Network (OpenVPN)" msgid "Virtual Private Network" msgstr "VIRTUAL PRIVATE NETWORK (OPENVPN)" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5044,45 +5022,11 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -#, fuzzy -#| msgid "Mode" -msgid "Migrate" -msgstr "MODE" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "PROFILE" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, fuzzy, python-format #| msgid "" #| "To connect to %(box_name)s's VPN, you need to download a profile and feed " @@ -5093,8 +5037,8 @@ msgstr "PROFILE" #| "how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "TO CONNECT TO %(box_name)s's VPN, YOU NEED TO DOWNLOAD A PROFILE AND FEED IT " @@ -5104,16 +5048,17 @@ msgstr "" "\">DOCUMENTATION ON RECOMMENDED CLIENTS AND INSTRUCTIONS ON HOW TO " "CONFIGURE THEM." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "PROFILE IS SPECIFIC TO EACH USER OF %(box_name)s. KEEP IT A SECRET." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "DOWNLOAD MY PROFILE" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, fuzzy, python-brace-format #| msgid "" #| "PageKite is a system for exposing %(box_name)s services when you don't " @@ -5131,13 +5076,13 @@ msgstr "" "SERVICES ARE UNREACHABLE FROM THE REST OF THE INTERNET. THIS INCLUDES THE " "FOLLOWING SITUATIONS:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, fuzzy, python-brace-format #| msgid "%(box_name)s is behind a restricted firewall." msgid "{box_name} is behind a restricted firewall." msgstr "%(box_name)s IS BEHIND A RESTRICTED FIREWALL." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, fuzzy, python-brace-format #| msgid "" #| "%(box_name)s is connected to a (wireless) router which you don't control." @@ -5145,7 +5090,7 @@ msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "%(box_name)s IS CONNECTED TO A (WIRELESS) ROUTER WHICH YOU DON'T CONTROL." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5153,7 +5098,7 @@ msgstr "" "YOUR ISP DOES NOT PROVIDE YOU AN EXTERNAL IP ADDRESS AND INSTEAD PROVIDES " "INTERNET CONNECTION THROUGH NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 #, fuzzy #| msgid "" #| "Your ISP does not provide you a static IP address and your IP address " @@ -5165,11 +5110,11 @@ msgstr "" "YOUR ISP DOES NOT PROVIDE YOU A STATIC IP ADDRESS AND YOUR IP ADDRESS " "CHANGES EVERTIME YOU CONNECT TO INTERNET." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "YOUR ISP LIMITS INCOMING CONNECTIONS." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, fuzzy, python-brace-format #| msgid "" #| "PageKite works around NAT, firewalls and IP-address limitations by using " @@ -5188,29 +5133,29 @@ msgstr "" "PROVIDER, FOR EXAMPLE PAGEKITE.NET. IN " "FUTURE IT MIGHT BE POSSIBLE TO USE YOUR BUDDY'S %(box_name)s FOR THIS." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 #, fuzzy #| msgid "Pagekite" msgid "PageKite" msgstr "PAGEKITE" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 #, fuzzy #| msgid "Public Visibility (PageKite)" msgid "Public Visibility" msgstr "PUBLIC VISIBILITY (PAGEKITE)" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 #, fuzzy #| msgid "PageKite Account" msgid "PageKite Domain" msgstr "PAGEKITE ACCOUNT" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "SERVER DOMAIN" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5218,31 +5163,31 @@ msgstr "" "SELECT YOUR PAGEKITE SERVER. SET \"PAGEKITE.NET\" TO USE THE DEFAULT " "PAGEKITE.NET SERVER." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "SERVER PORT" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "PORT OF YOUR PAGEKITE SERVER (DEFAULT: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "KITE NAME" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "EXAMPLE: MYBOX.PAGEKITE.ME" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "INVALID KITE NAME" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "KITE SECRET" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5250,27 +5195,27 @@ msgstr "" "A SECRET ASSOCIATED WITH THE KITE OR THE DEFAULT SECRET FOR YOUR ACCOUNT IF " "NO SECRET IS SET ON THE KITE." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "PROTOCOL" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "EXTERNAL (FRONTEND) PORT" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "INTERNAL (FREEDOMBOX) PORT" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "ENABLE SUBDOMAINS" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "DELETED CUSTOM SERVICE" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 #, fuzzy #| msgid "" #| "This service is available as a standard service. Please use the " @@ -5280,11 +5225,11 @@ msgstr "" "THIS SERVICE IS AVAILABLE AS A STANDARD SERVICE. PLEASE USE THE \"STANDARD " "SERVICES\" PAGE TO ENABLE IT. " -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "ADDED CUSTOM SERVICE" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "THIS SERVICE ALREADY EXISTS" @@ -5325,29 +5270,29 @@ msgstr "" "PROTOCOL/PORT COMBINATIONS THAT YOU ARE ABLE TO DEFINE HERE. FOR EXAMPLE, " "HTTPS ON PORTS OTHER THAN 443 IS KNOWN TO CAUSE PROBLEMS." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "WEB SERVER (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "SITE WILL BE AVAILABLE AT HTTP://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "WEB SERVER (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "SITE WILL BE AVAILABLE AT HTTPS://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "SECURE SHELL (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5393,8 +5338,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 #, fuzzy #| msgid "Restart Now" msgid "Restart" @@ -5444,6 +5389,39 @@ msgstr "" msgid "Shut Down Now" msgstr "SHUT DOWN NOW" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Enable Privoxy" +msgid "Privacy" +msgstr "ENABLE PRIVOXY" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 #, fuzzy #| msgid "" @@ -5498,7 +5476,7 @@ msgstr "PRIVOXY WEB PROXY" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "ACCESS {url} WITH PROXY {proxy} ON TCP{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "Quassel is an IRC application that is split into two parts, a \"core\" " @@ -5522,7 +5500,7 @@ msgstr "" "ONE OR MORE QUASSEL CLIENTS FROM A DESKTOP OR A MOBILE CAN BE USED TO " "CONNECT AND DISCONNECT FROM IT." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your DESKTOP AND MOBILE DEVICES ARE AVAILABLE." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 #, fuzzy #| msgid "Quassel IRC Client" msgid "IRC Client" @@ -5548,7 +5526,7 @@ msgstr "QUASSEL IRC CLIENT" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5558,19 +5536,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5629,7 +5607,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 #, fuzzy #| msgid "Configuration updated" msgid "Access rights configuration updated" @@ -5735,7 +5713,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5750,13 +5728,13 @@ msgstr "BRIDGE" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5765,31 +5743,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Network Time Server" msgid "Network File Storage" @@ -5879,19 +5857,19 @@ msgstr "KITE NAME" msgid "Action" msgstr "ACTIONS" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "FREEDOMBOX" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 #, fuzzy #| msgid "Add Service" msgid "Open Share" msgstr "ADD SERVICE" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 #, fuzzy #| msgid "Add Service" msgid "Group Share" @@ -5927,57 +5905,57 @@ msgstr "{name} DELETED." msgid "Error disabling share: {error_message}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 #, fuzzy #| msgid "Web Server" msgid "Web Search" msgstr "WEB SERVER" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 #, fuzzy #| msgid "Save Services" msgid "Safe Search" msgstr "SAVE SERVICES" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 #, fuzzy #| msgid "Mode" msgid "Moderate" msgstr "MODE" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -6159,14 +6137,14 @@ msgstr "BOOKMARKS (SHAARLI)" msgid "Shaarlier" msgstr "SHAARLI" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6175,107 +6153,107 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 #, fuzzy #| msgid "Service" msgid "Server" msgstr "SERVICE" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 #, fuzzy #| msgid "Server port" msgid "Server port number" msgstr "SERVER PORT" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 #, fuzzy #| msgid "Enable Shaarli" msgid "Sharing" msgstr "ENABLE SHAARLI" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 #, fuzzy #| msgid "Publish Key" msgid "Public share" msgstr "PUBLISH KEY" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 #, fuzzy #| msgid "This service already exists" msgid "A share with this name already exists." msgstr "THIS SERVICE ALREADY EXISTS" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -6318,30 +6296,30 @@ msgstr "" msgid "Add Share" msgstr "ADD SERVICE" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 #, fuzzy #| msgid "Edit User" msgid "Edit Share" msgstr "EDIT USER" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 #, fuzzy #| msgid "{name} deleted." msgid "Share deleted." msgstr "{name} DELETED." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6349,14 +6327,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 #, fuzzy #| msgid "Create User" msgid "Storage Snapshots" @@ -6464,7 +6442,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 #, fuzzy #| msgid "Delete %(name)s" msgid "Delete Snapshots" @@ -6516,65 +6494,65 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "packages not found" msgid "manually created" msgstr "PACKAGES NOT FOUND" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 #, fuzzy #| msgid "Create User" msgid "Manage Snapshots" msgstr "CREATE USER" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 #, fuzzy #| msgid "Configuration updated" msgid "Storage snapshots configuration updated" msgstr "CONFIGURATION UPDATED" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "ACTION ERROR: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 #, fuzzy #| msgid "Delete %(name)s" msgid "Deleted selected snapshots" msgstr "DELETE %(name)s" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6582,7 +6560,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "SECURE SHELL (SSH) SERVER" @@ -6621,14 +6599,6 @@ msgstr "" msgid "Fingerprint" msgstr "GPG FINGERPRINT" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6643,7 +6613,7 @@ msgstr "LOGIN" msgid "Logged out successfully." msgstr "PASSWORD CHANGED SUCCESSFULLY." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6651,159 +6621,159 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 #, fuzzy #| msgid "reStore" msgid "Storage" msgstr "RESTORE" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 #, fuzzy #| msgid "repro service is running" msgid "The device is already unmounting." msgstr "REPRO SERVICE IS RUNNING" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 #, fuzzy #| msgid "This service already exists" msgid "The device is already mounted." msgstr "THIS SERVICE ALREADY EXISTS" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 #, fuzzy #| msgid "repro service is not running" msgid "The device is not mounted." msgstr "REPRO SERVICE IS NOT RUNNING" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "INVALID HOSTNAME" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 #, fuzzy #| msgid "Download directory" msgid "Path is not a directory." msgstr "DOWNLOAD DIRECTORY" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 #, fuzzy #| msgid "Download directory" msgid "Directory" msgstr "DOWNLOAD DIRECTORY" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 #, fuzzy #| msgid "Add Service" msgid "Share" msgstr "ADD SERVICE" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6839,7 +6809,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6857,33 +6827,33 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, fuzzy, python-brace-format #| msgid "Error setting time zone: {exception}" msgid "Error expanding partition: {exception}" msgstr "ERROR SETTING TIME ZONE: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 #, fuzzy #| msgid "Password changed successfully." msgid "Partition expanded successfully." msgstr "PASSWORD CHANGED SUCCESSFULLY." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6891,7 +6861,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6903,22 +6873,22 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 #, fuzzy #| msgid "Installation" msgid "Administer Syncthing application" msgstr "INSTALLATION" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 #, fuzzy #| msgid "" #| "Tor is an anonymous communication system. You can learn more about it " @@ -6939,7 +6909,7 @@ msgstr "" "THE " "TOR BROWSER." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, fuzzy, python-brace-format #| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." msgid "" @@ -6947,42 +6917,42 @@ msgid "" "TCP port 9050." msgstr "A TOR SOCKS PORT IS AVAILABLE ON YOUR %(box_name)s ON TCP PORT 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 #, fuzzy #| msgid "Tor Hidden Service" msgid "Tor Onion Service" msgstr "TOR HIDDEN SERVICE" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "TOR BRIDGE RELAY" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "TOR RELAY PORT AVAILABLE" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "OBFS3 TRANSPORT REGISTERED" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "OBFS4 TRANSPORT REGISTERED" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "ACCESS URL {url} ON TCP{kind} VIA TOR" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "CONFIRM TOR USAGE AT {url} ON TCP{kind}" @@ -7098,13 +7068,13 @@ msgstr "HIDDEN SERVICE" msgid "Ports" msgstr "PORT" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "AN ERROR OCCURRED DURING CONFIGURATION." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error configuring app: {error}" @@ -7172,14 +7142,14 @@ msgstr "" msgid "Transmission" msgstr "TRANSMISSION BITTORRENT" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, the blogs and wikis will be available from /IKIWIKI." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -7209,12 +7179,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7222,8 +7192,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -7231,30 +7201,30 @@ msgstr "" msgid "Software Update" msgstr "SOFTWARE UPGRADES" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox Manual" msgid "FreedomBox Updated" msgstr "FREEDOMBOX MANUAL" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution update started" msgstr "AUTOMATIC UPGRADES DISABLED" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7438,57 +7408,57 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "AUTOMATIC UPGRADES ENABLED" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "ERROR WHEN CONFIGURING UNATTENDED-UPGRADES: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "AUTOMATIC UPGRADES ENABLED" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "AUTOMATIC UPGRADES DISABLED" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Distribution upgrade enabled" msgstr "AUTOMATIC UPGRADES ENABLED" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution upgrade disabled" msgstr "AUTOMATIC UPGRADES DISABLED" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "UPGRADE PROCESS STARTED." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "STARTING UPGRADE FAILED." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Starting distribution upgrade test." msgstr "AUTOMATIC UPGRADES ENABLED" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7496,15 +7466,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "USERS AND GROUPS" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "CHECK LDAP ENTRY \"{search_item}\"" @@ -7524,25 +7494,25 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Account" msgid "Authorization Password" msgstr "ADMINISTRATOR ACCOUNT" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "SHOW PASSWORD" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 #, fuzzy #| msgid "" #| "Select which services should be available to the new user. The user will " @@ -7563,13 +7533,13 @@ msgstr "" "ABLE TO LOG IN TO ALL SERVICES. THEY CAN ALSO LOG IN TO THE SYSTEM THROUGH " "SSH AND HAVE ADMINISTRATIVE PRIVILEGES (SUDO)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, fuzzy, python-brace-format #| msgid "Creating LDAP user failed." msgid "Creating LDAP user failed: {error}" msgstr "CREATING LDAP USER FAILED." -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, fuzzy, python-brace-format #| msgid "Failed to add new user to {group} group." msgid "Failed to add new user to {group} group: {error}" @@ -7589,45 +7559,45 @@ msgstr "" "SYSTEM WITHOUT USING A PASSWORD. YOU MAY ENTER MULTIPLE KEYS, ONE ON EACH " "LINE. BLANK LINES AND LINES STARTING WITH # WILL BE IGNORED." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "RENAMING LDAP USER FAILED." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "FAILED TO REMOVE USER FROM GROUP." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "FAILED TO ADD USER TO GROUP." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add user to group." msgid "Failed to change user status." msgstr "FAILED TO ADD USER TO GROUP." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "CHANGING LDAP USER PASSWORD FAILED." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, fuzzy, python-brace-format #| msgid "Failed to add new user to admin group." msgid "Failed to add new user to admin group: {error}" msgstr "FAILED TO ADD NEW USER TO ADMIN GROUP." -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, fuzzy, python-brace-format #| msgid "Failed to obtain certificate for domain {domain}: {error}" msgid "Failed to restrict console access: {error}" msgstr "FAILED TO OBTAIN CERTIFICATE FOR DOMAIN {domain}: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "USER ACCOUNT CREATED, YOU ARE NOW LOGGED IN" @@ -7644,12 +7614,12 @@ msgstr "SAVE PASSWORD" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "CREATE USER" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "DELETE USER" @@ -7694,17 +7664,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "USERS" @@ -7737,34 +7707,34 @@ msgstr "" msgid "Save Changes" msgstr "SAVE CHANGES" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "USER %(username)s CREATED." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "USER %(username)s UPDATED." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "EDIT USER" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "USER {user} DELETED." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "DELETING LDAP USER FAILED." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "CHANGE PASSWORD" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "PASSWORD CHANGED SUCCESSFULLY." @@ -8125,7 +8095,7 @@ msgstr "DELETE CONNECTION" msgid "Server deleted." msgstr "{name} DELETED." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8134,7 +8104,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8143,28 +8113,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "ADDRESS" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki and Blog" msgid "Website and Blog" @@ -8182,7 +8152,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8195,7 +8165,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8203,11 +8173,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -8260,119 +8230,113 @@ msgstr "" msgid "Finished: {name}" msgstr "SERVICE DISABLED: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing custom services" -msgid "Error running apt-get" -msgstr "EXISTING CUSTOM SERVICES" - -#: plinth/package.py:389 +#: plinth/package.py:348 #, fuzzy #| msgid "Installation" msgid "installing" msgstr "INSTALLATION" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 #, fuzzy #| msgid "Setting unchanged" msgid "media change" msgstr "SETTING UNCHANGED" -#: plinth/package.py:395 +#: plinth/package.py:354 #, fuzzy, python-brace-format #| msgid "Configuration" msgid "configuration file: {file}" msgstr "CONFIGURATION" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install" msgid "Installing app" msgstr "INSTALL" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error installing app: {error}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error updating app: {error}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Applications" msgid "App installed." msgstr "APPLICATIONS" -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "LAST UPDATE" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install" msgid "Uninstalling app" msgstr "INSTALL" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing packages: {string} {details}" msgid "Error uninstalling app: {error}" msgstr "ERROR INSTALLING PACKAGES: {string} {details}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Applications" msgid "App uninstalled." msgstr "APPLICATIONS" -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8441,62 +8405,62 @@ msgstr "INSTALLATION" msgid "Service %(service_name)s is not running." msgstr "SERVICE DISCOVERY SERVER IS NOT RUNNING" -#: plinth/templates/base.html:30 -#, fuzzy, python-format -#| msgid "Plinth administrative interface for the %(box_name)s" -msgid "Core functionality and web interface for %(box_name)s" -msgstr "PLINTH ADMINISTRATIVE INTERFACE FOR THE %(box_name)s" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 #, fuzzy #| msgid "Apps" msgid " Apps" msgstr "APPS" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "APPS" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 #, fuzzy #| msgid "System" msgid " System" msgstr "SYSTEM" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "SYSTEM" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "CHANGE PASSWORD" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 #, fuzzy #| msgid "Shut Down Now" msgid "Shut down" msgstr "SHUT DOWN NOW" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "LOG OUT" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 #, fuzzy #| msgid "Language" msgid "Select language" msgstr "LANGUAGE" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "LOG IN" @@ -8785,6 +8749,38 @@ msgstr "" msgid "Gujarati" msgstr "" +#, fuzzy +#~| msgid "Enable Dynamic DNS" +#~ msgid "Enable DNSSEC" +#~ msgstr "ENABLE DYNAMIC DNS" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "FIREWALL DAEMON IS NOT RUNNING. PLEASE RUN IT. FIREWALL COMES ENABLED BY " +#~ "DEFAULT ON %(box_name)s. ON ANY DEBIAN BASED SYSTEM (SUCH AS " +#~ "%(box_name)s) YOU MAY RUN IT USING THE COMMAND 'SERVICE FIREWALLD START' " +#~ "OR IN CASE OF A SYSTEM WITH SYSTEMD 'SYSTEMCTL START FIREWALLD'." + +#, fuzzy +#~| msgid "Mode" +#~ msgid "Migrate" +#~ msgstr "MODE" + +#, fuzzy +#~| msgid "Existing custom services" +#~ msgid "Error running apt-get" +#~ msgstr "EXISTING CUSTOM SERVICES" + +#, fuzzy, python-format +#~| msgid "Plinth administrative interface for the %(box_name)s" +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "PLINTH ADMINISTRATIVE INTERFACE FOR THE %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "NETWORK CONNECTIONS" diff --git a/plinth/locale/fr/LC_MESSAGES/django.po b/plinth/locale/fr/LC_MESSAGES/django.po index bb860d9b7..0e7cb78c4 100644 --- a/plinth/locale/fr/LC_MESSAGES/django.po +++ b/plinth/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: FreedomBox UI\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: French calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1063,23 +1056,23 @@ msgstr "" "cette application. Les utilisateurs ayant cet accès pourront utiliser toutes " "les collections." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Utilisation des collections de livres électroniques calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Bibliothèque de livres numériques" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Nom de la collection" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1088,7 +1081,7 @@ msgstr "" "caractères _ . et - sans espaces sont autorisés. Exemple : " "Ma_Bibliotheque_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Une collection portant ce nom existe déjà." @@ -1137,20 +1130,20 @@ msgstr "Ouvrir la collection %(library)s" msgid "Delete library %(library)s" msgstr "Supprimer la collection %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Collection créée." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Une erreur est survenue pendant la création de la collection." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} supprimé." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "La suppression de {name} a échoué : {error}" @@ -1201,7 +1194,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Administration du serveur" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1209,18 +1202,18 @@ msgstr "" "Cette page vous permet de modifier certains paramètres généraux comme le nom " "de machine, le nom de domaine, la page d’accueil du serveur web, etc." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Configuration générale" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Configurer" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1341,48 +1334,48 @@ msgstr "" "Les journaux contiennent des informations sur qui a accédé au système, ainsi " "que des informations de débogage sur différents services" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Erreur lors de la définition du nom de machine : {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Nom de machine configuré" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Erreur lors de la définition du nom de domaine : {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Nom de domaine configuré" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" "Erreur lors du changement de page d’accueil du serveur web : {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Page d’accueil du serveur web modifiée" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Erreur lors du changement de mode avancé : {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Les applications et fonctionnalités avancées seront affichées" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Les applications et les fonctionnalités avancées seront masquées" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1395,7 +1388,7 @@ msgstr "" "peuvent l’utiliser afin de mettre en relation des participants pour qui cela " "aurait été impossible autrement." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ejabberd qui peuvent l’utiliser en reportant les détails " "fournis ici dans leur configuration." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Assistant de VoIP" @@ -1470,11 +1463,11 @@ msgstr "Erreur lors de la modification du fuseau horaire : {exception}" msgid "Time zone set" msgstr "Fuseau horaire modifié" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge est un client BitTorrent avec une interface utilisateur web." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1483,16 +1476,16 @@ msgstr "" "il est fortement recommandé de le modifier immédiatement après l’activation " "du service." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Téléchargement de fichiers avec les applications BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Client web pour BitTorrent" @@ -1621,7 +1614,7 @@ msgstr "Résultat" msgid "Diagnostic Test" msgstr "Test de diagnostic" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1633,7 +1626,7 @@ msgstr "" "Et ceci empêchera d’autres utilisateurs de découvrir les services proposés " "par cette {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1651,7 +1644,7 @@ msgstr "" "d’assigner votre nom DNS à la nouvelle IP, de sorte que si quelqu’un sur " "Internet demande votre nom DNS, il obtiendra bien votre adresse IP courante." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1664,11 +1657,11 @@ msgstr "" "d’actualisation sur freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Client DNS dynamique" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Nom de domaine dynamique" @@ -1802,7 +1795,7 @@ msgstr "Ce champ est requis." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1857,7 +1850,7 @@ msgstr "Connexion refusée par le serveur" msgid "Already up-to-date" msgstr "Déjà à jour" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1865,7 +1858,7 @@ msgstr "" "XMPP est un protocole de communication ouvert et standardisé. Vous pouvez " "lancer et configurer ici votre serveur XMPP, appelé ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientutilisateur disposant d’un " "compte sur la {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn ou " "bien configurez un serveur externe." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Serveur de discussion" @@ -2018,7 +2011,7 @@ msgstr "" "Vous pouvez configurer le domaine de votre système sur la page Configurer." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -2029,7 +2022,7 @@ msgstr "" "aux clients de courriel d’accéder à votre boîte mel via les protocoles IMAP " "et POP3. Rspamd se charge des pourriels." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2041,7 +2034,7 @@ msgstr "" "Plusieurs FAI limitent aussi les courriels sortants. Certains retirent cette " "limite après une requête explicite. Voir le manuel pour plus de précisions." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2057,7 +2050,7 @@ msgstr "" "« postmaster » sont créés automatiquement, pointant vers le premier compte " "administrateur." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2065,7 +2058,7 @@ msgstr "" "L’appli Roundcube propose une " "interface Web pour accéder à vos courriels." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2196,7 +2189,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "Hôte/Cible/Valeur" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2208,7 +2201,7 @@ msgstr "" "Garder un pare-feu activé et correctement configuré réduit le risque des " "menaces provenant d’Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Pare-feu" @@ -2228,53 +2221,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} ({details}) non disponible pour les réseaux externes" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Le démon de pare-feu est arrêté. Veuillez le démarrer. Dans la configuration " -"d’origine de la %(box_name)s, le pare-feu est activé. Sur les systèmes basés " -"sur Debian (comme la %(box_name)s), vous pouvez démarrer le pare-feu en " -"utilisant la commande « service firewalld start » ou dans le cas d’un " -"système avec systemd, « systemctl start firewalld »." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Service/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Activé" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Désactivé" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Permis" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Permis (en interne uniquement)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Permis (en externe uniquement)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Bloqué" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2284,13 +2263,13 @@ msgstr "" "service, il est automatiquement permis par le pare-feu, si vous le " "désactivez, il est automatiquement désactivé dans le pare-feu." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Avancé" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2344,7 +2323,7 @@ msgstr "Démarrer la configuration initiale" msgid "Setup Complete" msgstr "Configuration initiale terminée" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2363,7 +2342,7 @@ msgstr "" "en ligne de commande ou l’un des nombreux clients graphiques existants. " "Partagez ainsi votre code source avec d’autres, tout autour du monde." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2371,68 +2350,68 @@ msgstr "" "Pour en apprendre plus sur l’utilisation de Git, consultez ce tutoriel Git." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Accès aux dépôts Git en lecture et en écriture" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Hébergement Git simple" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Adresse du dépôt invalide." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Nom de dépôt invalide." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Nom du dépôt à créer, ou adresse (URL) d’un dépôt existant pour l’importer." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Description du dépôt" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Paramètre optionnel, pour affichage dans Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Propriétaire du dépôt" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Dépôt privé" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Ne permet l’accès à ce dépôt qu’aux utilisateurs autorisés." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Un dépôt existe déjà avec ce nom." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Nom du dépôt" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Une chaîne alpha-numérique qui identifie de manière unique le dépôt." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Branche par défaut" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb affiche cette branche comme branche par défaut." @@ -2476,19 +2455,19 @@ msgstr "Supprimer le dépôt Git %(name)s" msgid "Delete this repository permanently?" msgstr "Supprimer définitivement ce dépôt ?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Dépôt créé." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Une erreur est survenue pendant la création du dépôt." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Dépôt modifié." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Modifier le dépôt" @@ -2866,7 +2845,7 @@ msgstr "À propos de la {box_name}" msgid "{box_name} Manual" msgstr "Manuel {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2878,7 +2857,7 @@ msgstr "" "fournit de l’anonymat en envoyant du trafic chiffré sur un réseau distribué " "actionné par des volontaires partout sur la planète." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2886,7 +2865,7 @@ msgstr "" "Vous trouverez plus d’informations à propos d’I2P sur le site web de leur projet." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2894,19 +2873,19 @@ msgstr "" "L’interface web fournie vous guidera dans les étapes de configuration lors " "de votre première visite." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Gestion de l’application I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Réseau d’anonymisation" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "Serveur mandataire I2P" @@ -2952,7 +2931,7 @@ msgstr "" "un réseau de pair à pair. Téléchargez des fichiers en ajoutant des torrents " "ou en créant un nouveau torrent pour partager un fichier." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2963,7 +2942,7 @@ msgstr "" "fonctionnalités de blogue habituelles telles que les commentaires et les " "flux RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2978,15 +2957,15 @@ msgstr "" "utilisateurs dans la configuration des utilisateurs." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki et blogue" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Consultation et modification des applications de wiki" @@ -3043,41 +3022,41 @@ msgstr "" "commentaires, ainsi que l’historique des révisions. Voulez-vous supprimer " "définitivement ce wiki ou blogue ?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Wiki {name} créé." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Échec de la création du wiki : {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blogue {name} créé." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Échec de la création du blogue : {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} supprimé." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Échec de la suppression de {title} : {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted est un serveur pour Gobby, un éditeur de texte collaboratif." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3088,11 +3067,11 @@ msgstr "" "Gobby et installez-le. Lancez ensuite Gobby, sélectionnez « Connect to " "Server » et saisissez le nom de domaine de la {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Serveur Gobby" @@ -3140,7 +3119,7 @@ msgstr "Salle de visio Janus" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Information de licence JavaScript" @@ -3160,7 +3139,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Client de discussion" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3175,7 +3154,7 @@ msgstr "" "chaque domaine disponible. Elle le fait en prouvant qu’elle est propriétaire " "du domaine auprès de l’autorité de certification « Let’s Encrypt »." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3189,15 +3168,15 @@ msgstr "" "fr/repository/\">conditions d’utilisation de Let’s Encrypt avant " "d’utiliser ce service." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let’s Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certificats de chiffrement" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Test impossible : aucun domaine n’est configuré." @@ -3262,7 +3241,7 @@ msgstr "" "Aucun domaine n’a été configuré. Configurez des " "domaines pour pouvoir obtenir leurs certificats." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3271,36 +3250,36 @@ msgstr "" "Le certificat du domaine {domain} a été révoqué. Cette modification peut " "nécessiter quelques instants avant de prendre effet." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" "La révocation du certificat pour le domaine {domain} a échoué : {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Le certificat pour le domaine {domain} a été obtenu avec succès" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "L’obtention du certificat pour le domaine {domain} a échoué : {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Le certificat pour le domaine {domain} a été supprimé" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" "La suppression du certificat pour le domaine {domain} a échoué : {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3318,7 +3297,7 @@ msgstr "" "un serveur Matrix donné peuvent converser avec des utilisateurs sur tous les " "autres serveurs Matrix grâce la fédération." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3328,7 +3307,7 @@ msgstr "" "Installez pour cela l’application Coturn ou " "bien configurez un serveur externe." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3435,7 +3414,7 @@ msgstr "" "valide. Rendez-vous sur Let’s Encrypt " "pour en obtenir un." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3449,7 +3428,7 @@ msgstr "" "web de type wiki, pour prendre des notes ou pour collaborer sur des projets " "entre amis." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3464,7 +3443,7 @@ msgstr "" "vous rendant sur la page Special:CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3472,12 +3451,12 @@ msgstr "" "Toute personne ayant le lien vers ce wiki peut le consulter. Seuls les " "utilisateurs connectés avec leur compte peuvent y apporter des modifications." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3562,35 +3541,35 @@ msgstr "" "Échec de la mise à jour du mot passe. Veuillez choisir un mot de passe plus " "sûr" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Inscriptions publiques activées" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Inscriptions publiques désactivées" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Mode privé activé" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Mode privé désactivé" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Thème par défaut modifié" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Nom de domaine modifié" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Nom de site modifié" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3603,11 +3582,11 @@ msgstr "" "au serveur, vous devez disposer d’un client Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Bac à sable cubique" @@ -3661,7 +3640,7 @@ msgstr "" msgid "Address" msgstr "Adresse" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3850,7 +3829,7 @@ msgstr "Secure Shell" msgid "Services" msgstr "Services" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3859,7 +3838,7 @@ msgstr "" "le Wi-Fi ou le protocole PPPoE. Partage de cette connexion avec d’autres " "appareils du réseau local." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3867,7 +3846,7 @@ msgstr "" "Les périphériques gérés par d’autres méthodes pourraient ne pas être " "disponibles pour être configurés ici." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Réseau" @@ -4310,7 +4289,7 @@ msgstr "Modifier la connexion" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Modifier" @@ -4415,7 +4394,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Méthode" @@ -4431,7 +4410,7 @@ msgstr "Serveur DNS" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Défaut" @@ -4444,7 +4423,7 @@ msgid "This connection is not active." msgstr "Cette connexion n’est pas active." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Sécurité" @@ -5041,7 +5020,7 @@ msgstr "Connexion {name} supprimée." msgid "Failed to delete connection: Connection not found." msgstr "Échec de suppression de la connexion : connexion introuvable." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -5059,20 +5038,20 @@ msgstr "" "d’accéder au reste d’Internet au travers de la {box_name} pour une sécurité " "et un anonymat accrus." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Connexion aux services VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Réseau privé virtuel" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5084,63 +5063,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" -"Migration vers la cryptographie ECC (Cryptographie basée sur les Courbes " -"Elliptiques)" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Votre installation OpenVPN utilise actuellement le protocole de " -"cryptographie RSA. La migration vers la Cryptographie basée sur les Courbes " -"Elliptiques (Elliptic Curve Cryptography), plus moderne, accélère " -"l’établissement de la connexion et améliore la sécurité. Cette opération est " -"irréversible. Cela ne devrait prendre que quelques minutes sur la plupart " -"des mini-ordinateurs SBC (Single Board Computers)." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Toutes les nouvelles installations de OpenVPN sur %(box_name)s utiliseront " -"la Cryptographie des Courbes Elliptiques (ECC) par défaut. Nous recommandons " -"de migrer aussi vite que possible." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Attention : Les profils client existants seront invalidés par cette " -"opération. Tous les utilisateurs de OpenVPN sur %(box_name)s devront " -"télécharger leurs nouveaux profils. Des clients OpenVPN compatibles avec la " -"cryptographie ECC devront être utilisés pour se connecter à ce serveur." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migration" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Pour vous connecter au réseau privé virtuel VPN de la %(box_name)s, vous " @@ -5150,18 +5087,19 @@ msgstr "" "pour connaître les clients recommandés et leurs instructions de " "configuration." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Le profil est propre à chaque utilisateur de la %(box_name)s. Gardez-le " "secret." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Télécharger mon profil" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5175,18 +5113,18 @@ msgstr "" "reste de l’Internet. Cela se produit en général dans les situations " "suivantes :" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "La {box_name} est derrière un pare-feu avec des restrictions." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "La {box_name} est connectée à un réseau (sans fil) que vous ne contrôlez pas." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5194,7 +5132,7 @@ msgstr "" "Votre FAI ne vous fournit pas d’adresse IP externe, mais une connexion " "Internet via une traduction d’adresses réseau (NAT)." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5202,11 +5140,11 @@ msgstr "" "Votre FAI ne vous fournit pas une adresse IP statique, elle change à chaque " "fois que vous vous connectez à Internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Votre FAI limite les connexions entrantes." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5222,23 +5160,23 @@ msgstr "" "a>. Il se pourrait que dans le futur, l’utilisation de la {box_name} d’un " "ami pour cela soit également proposée." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Visibilité publique" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Domaine PageKite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Domaine du serveur" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5246,31 +5184,31 @@ msgstr "" "Choisissez votre serveur pagekite. Saisissez « pagekite.net » pour utiliser " "le serveur pagekite.net par défaut." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Port serveur" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Port de votre serveur pagekite (par défaut : 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Nom Kite" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Exemple : monpc.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Nom Kite invalide" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite secret" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5278,35 +5216,35 @@ msgstr "" "Un secret associé au kite ou le secret par défaut de votre compte si aucun " "secret n’est défini sur ce kite." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protocole" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "port externe (du frontal)" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "port interne (de la freedombox)" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Activer les sous-domaines" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Service personnalisé supprimé" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Ce service est déjà disponible sous forme standard." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Service personnalisé ajouté" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Ce service existe déjà" @@ -5344,29 +5282,29 @@ msgstr "" "définition. Par exemple, l’utilisation de ports autre que 443 pour le " "protocole HTTPS est connu pour causer des problèmes." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Serveur web (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Le site sera accessible sur http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Serveur web (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Le site sera accessible sur https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Shell sécurisé (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5418,8 +5356,8 @@ msgstr "" "Une installation ou une mise à niveau est en cours. Il est préférable " "d’attendre la fin de l’opération avant d’éteindre ou de redémarrer." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Redémarrer" @@ -5469,6 +5407,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Éteindre immédiatement" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5512,7 +5483,7 @@ msgstr "Serveur mandataire web" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Accéder à l’URL {url} avec le mandataire {proxy} sur tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5529,7 +5500,7 @@ msgstr "" "toujours en ligne sur IRC. Un ou plusieurs clients Quassel sur ordinateur ou " "sur mobile peuvent ensuite se connecter ou se déconnecter du « cœur »." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile sont disponibles pour " "téléchargement." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Client IRC" @@ -5554,7 +5525,7 @@ msgstr "Client IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5571,7 +5542,7 @@ msgstr "" "cliente compatible. Tous les utilisateur disposant d’un compte sur la " "{box_name} ont accès à Radicale." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5582,12 +5553,12 @@ msgstr "" "charge l’ajout d’événements ou de contacts, opérations qui doivent être " "réalisées avec un client dédié." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Agenda et carnet d’adresses" @@ -5663,7 +5634,7 @@ msgstr "" "recherche pour afficher la liste de vos agendas et carnets d’adresses " "existants." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Configuration des droits d’accès mise à jour" @@ -5759,7 +5730,7 @@ msgstr "" "a> pour suivre différents sites internet. Lors de l’ajout d’un fil, activez " "l’authentification et utilisez les identifiants de {box_name}." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Lecture et abonnement à des flux d’actualités" @@ -5772,7 +5743,7 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "Générateur de fil RSS" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5780,7 +5751,7 @@ msgstr "" "Samba permet de partager des fichiers et des répertoires entre la FreedomBox " "et d’autres machines de votre réseau local." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5794,11 +5765,11 @@ msgstr "" "smb://{hostname}.local (sur Linux et Mac). Vous pourrez choisir parmi trois " "types de partages : " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Partage ouvert : accessible par tout le monde sur votre réseau local." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5806,7 +5777,7 @@ msgstr "" "Partage de groupe : accessible uniquement aux utilisateurs de la FreedomBox " "qui sont membres du groupe freedombox-share." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5814,15 +5785,15 @@ msgstr "" "Partage de dossier personnel : chaque utilisateur du groupe freedombox-share " "a son propre espace privé." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Accès aux partages privés" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Stockage de fichiers réseau" @@ -5911,15 +5882,15 @@ msgstr "Nom du partage" msgid "Action" msgstr "Action" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "Disque du système FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Ouvrir un partage" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Partage de groupe" @@ -5945,7 +5916,7 @@ msgstr "Partage désactivé." msgid "Error disabling share: {error_message}" msgstr "Erreur lors de la désactivation du partage : {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5954,7 +5925,7 @@ msgstr "" "privée. Il rassemble et affiche les résultats de plusieurs moteurs de " "recherche." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5962,41 +5933,41 @@ msgstr "" "Searx peut être utilisé pour éviter le pistage et le profilage fait par les " "moteurs de recherche. Par défaut il ne stocke aucun cookie." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Recherches sur le Web" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Recherche web" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Recherche sûre" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Choisissez le filtre de famille à appliquer par défaut à vos résultats de " "recherche." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Modéré" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Strict" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Permettre l’accès public" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Permettre l’utilisation de cette application à n’importe qui parvenant à y " @@ -6183,7 +6154,7 @@ msgstr "Signets" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6193,7 +6164,7 @@ msgstr "" "votre trafic Internet. Il peut être utilisé pour contourner les problèmes de " "filtrage ou de censure d’Internet." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6207,7 +6178,7 @@ msgstr "" "mandataire, et leurs flux de données seront chiffrés et transmis vers " "l’extérieur au travers du serveur Shadowsocks." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6216,44 +6187,44 @@ msgstr "" "l’URL de mandataire SOCKS5 sur votre appareil, navigateur ou application " "avec l’URL http://adresse_freedombox:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Mandataire Socks5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Recommandé" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Serveur" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Nom ou adresse IP du serveur" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Numéro de port du serveur" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Mot de passe utilisé pour chiffrer les données. Doit correspondre au mot de " "passe du serveur." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" "Méthode de chiffrement. Doit correspondre à celle qui a été configurée sur " "le serveur." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6262,15 +6233,15 @@ msgstr "" "« Partages » vous permet de partager des fichiers et répertoires de votre " "{box_name} sur Internet avec des groupes d’utilisateurs bien définis." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Partages" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Nom du partage" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6278,29 +6249,29 @@ msgstr "" "Une chaîne alpha-numérique en minuscules qui identifie de manière unique le " "partage. Par exemple : media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Chemin du partage" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Chemin d’un répertoire sur ce serveur que vous souhaitez partager." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Partage public" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" "Les fichiers de ce répertoire seront accessible à toute personne possédant " "le lien vers ce partage." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Groupes d’utilisateurs autorisés à consulter les fichiers du partage :" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6308,11 +6279,11 @@ msgstr "" "Les utilisateurs des groupes sélectionnés pourront lire les fichiers du " "partage." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Un partage existe déjà avec ce nom." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" "Les partages peuvent être soit publics soit partagés avec au moins un groupe" @@ -6350,19 +6321,19 @@ msgstr "Partage créé." msgid "Add Share" msgstr "Ajouter un partage" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Partage modifié." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Modifier le partage" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Partage supprimé." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6373,7 +6344,7 @@ msgstr "" "utilisés pour ramener le système à un état précédent connu pour être " "fonctionnel, dans le cas ou des changements non désirés ont été appliqués." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6385,7 +6356,7 @@ msgstr "" "instantanés plus anciens seront supprimés automatiquement en fonction du " "paramétrage qui suit." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for sauvegardes car ils sont forcément conservés sur la même partition. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Instantanés de disque" @@ -6500,7 +6471,7 @@ msgstr "Date" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Supprimer les instantanés" @@ -6554,58 +6525,58 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Revenir à l’instantané n° %(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "créé manuellement" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "historique" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Gestion des instantanés" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Instantané créé." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Configuration des instantanés de disque mise à jour" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Erreur lors de l’opération : {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Supprimer les instantanés sélectionnés" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" "L’instantané est en cours d’utilisation. Veuillez réessayer ultérieurement." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Retour à l’instantané n° {number} effectué." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Le système doit être redémarré pour terminer le retour en arrière." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Revenir à l’instantané" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6617,7 +6588,7 @@ msgstr "" "effectuer des tâches d’administration, copier des fichiers ou bien faire " "fonctionner d’autres services en utilisant de telles connexions." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Serveur Secure Shell (SSH)" @@ -6655,14 +6626,6 @@ msgstr "Algorithme" msgid "Fingerprint" msgstr "Empreinte" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "Authentification SSH par mot de passe désactivée." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Authentification SSH par mot de passe activée." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Authentification unique" @@ -6675,7 +6638,7 @@ msgstr "S’identifier" msgid "Logged out successfully." msgstr "Déconnecté avec succès." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6687,109 +6650,109 @@ msgstr "" "d’utilisation, monter et démonter des médias amovibles, étendre la partition " "racine, etc." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Stockage" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} octets" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} Kio" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} Mio" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} Gio" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} Tio" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "L’opération a échoué." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "L’opération a été annulée." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Le périphérique est déjà en train d’être démonté." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "L’opération n’est pas disponible par manque d’un pilote ou d’un outil adapté." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "L’opération ne s’est pas terminée." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" "L’opération réveillerait un disque qui se trouve dans un état de veille " "profond." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Tentative de démontage d’un périphérique en cours d’utilisation." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "L’opération a déjà été annulée." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Vous n’êtes pas autorisé à effectuer l’opération demandée." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Le périphérique est déjà monté." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Le périphérique n’est pas monté." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Vous n’êtes pas autorisé à utiliser l’option demandée." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Le périphérique est monté par un autre utilisateur." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Espace disque faible sur la partition système : {percent_used}% utilisés, " "{free_space} libres." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Espace disque faible" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Panne de disque imminente" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6799,39 +6762,39 @@ msgstr "" "Copiez toutes les données qui s’y trouvent tant qu’il est encore temps et " "remplacez le disque." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Nom de répertoire invalide." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Le répertoire n’existe pas." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Le chemin n’est pas un répertoire." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Le répertoire n’est pas lisible par l’utilisateur." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "L’utilisateur ne peut pas écrire dans le répertoire." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Répertoire" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Sous-répertoire (optionnel)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Partage" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Autre répertoire (indiquer ci-dessous)" @@ -6869,7 +6832,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Étendre la partition racine" @@ -6893,30 +6856,30 @@ msgstr "" "votre partition racine disposera de %(expandable_root_size)s d’espace disque " "supplémentaire." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Erreur lors de l’extension de la partition : {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Extension de la partition réalisée avec succès." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} peut être débranché en toute sécurité." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Le périphérique peut être débranché en toute sécurité." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Erreur lors de l’éjection du périphérique : {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6929,7 +6892,7 @@ msgstr "" "seront automatiquement répliquées aux autres appareils qui utilisent " "Syncthing." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6949,20 +6912,20 @@ msgstr "" "{box_name} n’est accessible qu’aux utilisateurs membres des groupes " "« admin » et « syncthing-access »." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Administration de l’application Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Synchronisation de fichiers" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6976,7 +6939,7 @@ msgstr "" "recommande l’utilisation du Navigateur Tor." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6985,40 +6948,40 @@ msgstr "" "Un port SOCKS pour Tor est accessible sur votre {box_name} pour les réseaux " "internes via le port TCP 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Service onion Tor" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Mandataire Socks Tor" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Relais Tor de type pont (« bridge relay »)" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Le port du relais Tor est disponible" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Abonné au transport obfs3" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Abonné au transport obfs4" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Accédez à l’URL {url} sur tcp{kind} via Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Confirmez l’utilisation de Tor pour {url} sur tcp{kind}" @@ -7140,11 +7103,11 @@ msgstr "Service Onion" msgid "Ports" msgstr "Ports" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Mise à jour de la configuration" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Erreur lors de la configuration de l’application : {error}" @@ -7208,7 +7171,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7219,7 +7182,7 @@ msgstr "" "n’importe quel appareil tout en restant au plus près du design d’une " "application de bureau complète." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7229,7 +7192,7 @@ msgstr "" "\"{users_url}\">n’importe quel utilisateur appartenant au groupe de " "lecteur de fil." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7238,11 +7201,11 @@ msgstr "" "ordinateur, saisissez l’URL tt-rss-app pour " "vous connecter." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Lecteur de flux d’informations" @@ -7250,14 +7213,14 @@ msgstr "Lecteur de flux d’informations" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Rechercher et installer les dernières mises à jour logicielles et les " "correctifs de sécurité." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7271,22 +7234,22 @@ msgstr "" "nécessaire, il est effectué à 2h00, rendant indisponible l’ensemble des " "applications pour une courte période." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Mise à jour du système" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox mise à jour" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Impossible de lancer la mise à niveau de la distribution" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7297,11 +7260,11 @@ msgstr "" "sont disponibles. Si activée, la mise à niveau automatique de la " "distribution sera retentée dans 24H." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Mise à niveau de la distribution démarrée" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7483,46 +7446,46 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Lancer le test de mise à niveau de la distribution" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" "Erreur lors de la configuration du système de mise à jour automatique " "« unattended-upgrades » : {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Mises à niveau automatiques activées" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Mises à niveau automatiques désactivées" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Mise à niveau de la distribution activée" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Mise à niveau de la distribution désactivée" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Mise à jour lancée." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Le lancement de la mise à niveau a échoué." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Mise à jour régulière des fonctionnalités activée." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Démarrage du test de mise à niveau de la distribution." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7533,7 +7496,7 @@ msgstr "" "Certaines applis demandent en outre que les comptes soient membres d’un " "groupe particulier pour pouvoir accéder à l’application." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7545,15 +7508,15 @@ msgstr "" "principale. En revanche, seuls les utilisateurs membres du groupe admin peuvent modifier les applications ou changer les paramètres système." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Utilisateurs et groupes" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Accès à tous les services et à la configuration du système" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Vérification de l’entrée LDAP « {search_item} »" @@ -7573,11 +7536,11 @@ msgstr "" "Requis. 150 caractères ou moins. Lettres anglaises, chiffres et @/./-/_ " "uniquement." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Mot de passe actuel" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7585,11 +7548,11 @@ msgstr "" "Veuillez saisir votre mot de passe de l’utilisateur « {user} » pour " "confirmer ces modifications de compte." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Mot de passe incorrect." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7604,12 +7567,12 @@ msgstr "" "peuvent également se connecter au système avec Secure Shell (SSH) et obtenir " "les privilèges d’administrateur (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "La création de l’utilisateur LDAP a échoué : {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "L’ajout du nouvel utilisateur au groupe {group} a échoué : {error}" @@ -7629,42 +7592,42 @@ msgstr "" "plusieurs clefs, une sur chaque ligne. Les lignes vides et celles commençant " "par # sont ignorées." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Le changement du nom de l’utilisateur LDAP a échoué." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Échec du retrait de l’utilisateur du groupe." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Échec de l’ajout de l’utilisateur au groupe." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Échec du paramétrage des clefs SSH." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Échec du changement de statut de l’utilisateur." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Le changement du mot de passe de l’utilisateur LDAP a échoué." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "L’ajout du nouvel utilisateur au groupe admin a échoué : {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" "La mise en place des restrictions d’accès à la console à échoué : {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Compte utilisateur créé, vous êtes maintenant connecté" @@ -7681,12 +7644,12 @@ msgstr "Sauvegarder le mot de passe" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Créer un utilisateur" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Supprimer Utilisateur" @@ -7728,13 +7691,19 @@ msgid "The following administrator accounts exist in the system." msgstr "Les comptes administrateurs suivants sont présents sur le système." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Veuillez supprimer ces comptes depuis la ligne de commande et rafraîchir " "cette page pour pouvoir créer un compte utilisable avec la %(box_name)s. " @@ -7744,7 +7713,7 @@ msgstr "" "étape." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Utilisateurs" @@ -7777,34 +7746,34 @@ msgstr "" msgid "Save Changes" msgstr "Appliquer les changements" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Utilisateur %(username)s créé." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Utilisateur %(username)s mis à jour." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Modification de l’utilisateur" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Utilisateur {user} supprimé." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "La suppression de l’utilisateur LDAP a échoué." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Changer Mot de Passe" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Le mot de passe a été changé." @@ -8147,7 +8116,7 @@ msgstr "Supprimer la connexion à un serveur" msgid "Server deleted." msgstr "Serveur supprimé." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8162,7 +8131,7 @@ msgstr "" "thèmes. L’interface d’administration et les pages Web produites sont " "compatibles avec les appareils mobiles." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8177,7 +8146,7 @@ msgstr "" "l’interface d’administration pour améliorer les URL de vos pages et de vos " "billets de blogue." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8188,7 +8157,7 @@ msgstr "" "href=\"/wordpress/wp-admin/\">page d’administration à vos favoris pour y " "accéder ultérieurement." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8199,12 +8168,12 @@ msgstr "" "la mise à jour de modules additionnels et de thèmes se fait à vos risques et " "périls." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Site web et blogue" @@ -8222,7 +8191,7 @@ msgstr "" "WordPress. N’activez cette option qu’après avoir réalisé la configuration " "initiale de WordPress." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8245,7 +8214,7 @@ msgstr "" "recherche, de carte et de calendrier. Les photos peuvent être partagées " "unitairement avec d’autres en leur envoyant un lien direct." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8256,11 +8225,11 @@ msgstr "" "l’administrateur Zoph. Pour ajouter des utilisateurs ceux-ci doivent être " "créés à la fois sur la {box_name} et dans Zoph avec le même identifiant." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Photothèque" @@ -8314,96 +8283,92 @@ msgstr "Attente du démarrage de : {name}" msgid "Finished: {name}" msgstr "Terminé : {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Le paquet {expression} n’est pas disponible à l’installation" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Le paquet {package_name} est à la dernière version ({latest_version})" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "Erreur d’exécution d’« apt-get »" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "installation en cours" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "téléchargement en cours" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "changement de support" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "fichier de configuration : {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Aucune réponse du gestionnaire de paquets" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Installation de l’application" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Mise à jour de l’application" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Erreur lors de l’installation de l’appli : {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Erreur lors de la mise à jour de l’appli : {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Erreur lors de l’installation de l’appli : {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Erreur lors de la mise à jour de l’appli : {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "Application installée." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "Application mise à jour" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Désinstallation de l’application" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Erreur lors de la désinstallation de l’appli : {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Erreur lors de la désinstallation de l’appli : {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "Application désinstallée." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Mise à jour des paquets de l’application" @@ -8464,53 +8429,54 @@ msgstr "Installation" msgid "Service %(service_name)s is not running." msgstr "Le service %(service_name)s n’est pas actif." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Fonctions de base et interface web de la %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Accueil" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Accueil" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Applis" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Applis" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Système" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Système" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Changer le mot de passe" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Éteindre" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Se déconnecter" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Choisir la langue" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "S’identifier" @@ -8804,6 +8770,81 @@ msgstr "avant la désinstallation de {app_id}" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Activer DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Activer les extensions de sécurité DNS (DNSSEC)" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Le démon de pare-feu est arrêté. Veuillez le démarrer. Dans la " +#~ "configuration d’origine de la %(box_name)s, le pare-feu est activé. Sur " +#~ "les systèmes basés sur Debian (comme la %(box_name)s), vous pouvez " +#~ "démarrer le pare-feu en utilisant la commande « service firewalld start » " +#~ "ou dans le cas d’un système avec systemd, « systemctl start firewalld »." + +#~ msgid "Migrate to ECC" +#~ msgstr "" +#~ "Migration vers la cryptographie ECC (Cryptographie basée sur les Courbes " +#~ "Elliptiques)" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Votre installation OpenVPN utilise actuellement le protocole de " +#~ "cryptographie RSA. La migration vers la Cryptographie basée sur les " +#~ "Courbes Elliptiques (Elliptic Curve Cryptography), plus moderne, accélère " +#~ "l’établissement de la connexion et améliore la sécurité. Cette opération " +#~ "est irréversible. Cela ne devrait prendre que quelques minutes sur la " +#~ "plupart des mini-ordinateurs SBC (Single Board Computers)." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Toutes les nouvelles installations de OpenVPN sur %(box_name)s " +#~ "utiliseront la Cryptographie des Courbes Elliptiques (ECC) par défaut. " +#~ "Nous recommandons de migrer aussi vite que possible." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Attention : Les profils client existants seront invalidés par " +#~ "cette opération. Tous les utilisateurs de OpenVPN sur %(box_name)s " +#~ "devront télécharger leurs nouveaux profils. Des clients OpenVPN " +#~ "compatibles avec la cryptographie ECC devront être utilisés pour se " +#~ "connecter à ce serveur." + +#~ msgid "Migrate" +#~ msgstr "Migration" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "Authentification SSH par mot de passe désactivée." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Authentification SSH par mot de passe activée." + +#~ msgid "Error running apt-get" +#~ msgstr "Erreur d’exécution d’« apt-get »" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Fonctions de base et interface web de la %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Connexions réseau" diff --git a/plinth/locale/gl/LC_MESSAGES/django.po b/plinth/locale/gl/LC_MESSAGES/django.po index 0c2741d86..ba3776b73 100644 --- a/plinth/locale/gl/LC_MESSAGES/django.po +++ b/plinth/locale/gl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-01-18 12:32+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Galician calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1025,20 +1018,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1076,24 +1069,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1189,47 +1182,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Configurar a páxina de inicio do servidor web" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1237,7 +1230,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1467,11 +1460,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1583,7 +1576,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1638,13 +1631,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1766,14 +1759,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1781,7 +1774,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1791,13 +1784,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1924,7 +1917,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1932,7 +1925,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1952,61 +1945,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2052,7 +2036,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2063,73 +2047,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2173,19 +2157,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2480,7 +2464,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2488,31 +2472,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2549,14 +2533,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2565,15 +2549,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2627,41 +2611,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2669,11 +2653,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2719,7 +2703,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2737,7 +2721,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2747,7 +2731,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2755,15 +2739,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2826,41 +2810,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2870,14 +2854,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2958,7 +2942,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2966,7 +2950,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2975,18 +2959,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3057,35 +3041,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3094,11 +3078,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3143,7 +3127,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3304,19 +3288,19 @@ msgstr "" msgid "Services" msgstr "Descubrimento de servizo" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3662,7 +3646,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3767,7 +3751,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3783,7 +3767,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3796,7 +3780,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4334,7 +4318,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4345,20 +4329,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4368,61 +4352,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4431,33 +4383,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4466,87 +4418,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4580,29 +4532,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4644,8 +4596,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4687,6 +4639,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4718,7 +4701,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4729,7 +4712,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4749,7 +4732,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4759,19 +4742,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4830,7 +4813,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4897,7 +4880,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4910,13 +4893,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4925,31 +4908,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5027,17 +5010,17 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5065,51 +5048,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "Produciuse un erro ao instalar o aplicativo: {error}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5262,14 +5245,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5278,97 +5261,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5405,26 +5388,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5432,14 +5415,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5533,7 +5516,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5581,59 +5564,59 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Manual" msgid "manually created" msgstr "Manual" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5641,7 +5624,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5674,14 +5657,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5694,7 +5669,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5702,143 +5677,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5872,7 +5847,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5890,30 +5865,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5921,7 +5896,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5933,20 +5908,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5955,47 +5930,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6093,11 +6068,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6150,31 +6125,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6182,12 +6157,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6195,35 +6170,35 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox Updated" msgstr "FreedomBox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6375,51 +6350,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6427,15 +6402,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6453,21 +6428,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6476,12 +6451,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6497,41 +6472,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6548,12 +6523,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6591,17 +6566,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6632,34 +6607,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6970,7 +6945,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6979,7 +6954,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6988,26 +6963,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7021,7 +6996,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7034,7 +7009,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7042,11 +7017,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7096,108 +7071,104 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Produciuse un erro ao instalar o aplicativo: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Produciuse un erro ao instalar o aplicativo: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Produciuse un erro ao instalar o aplicativo: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Produciuse un erro ao instalar o aplicativo: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Aplicativo instalado." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "Produciuse un erro ao instalar o aplicativo: {error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Produciuse un erro ao instalar o aplicativo: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Produciuse un erro ao instalar o aplicativo: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Aplicativo instalado." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7248,53 +7219,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/gu/LC_MESSAGES/django.po b/plinth/locale/gu/LC_MESSAGES/django.po index bc170825e..2a6446071 100644 --- a/plinth/locale/gu/LC_MESSAGES/django.po +++ b/plinth/locale/gu/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-01-18 12:32+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Gujarati calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Documentation" msgid "Name of the new library" msgstr "દસ્તાવેજીકરણ" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1085,20 +1078,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1143,24 +1136,24 @@ msgstr "કોકપિટ" msgid "Server Administration" msgstr "સર્વર સંચાલન" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "સામાન્ય ગોઠવણી" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "ગોઠવો" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1267,49 +1260,49 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "હોસ્ટનું નામ સ્થાપિત કરતાં ભૂલ થઇ: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "હોસ્ટનું નામ સ્થાપિત કર્યું" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "ક્ષેત્રીય નામ સ્થાપિત કરતાં ભૂલ થઇ: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "ક્ષેત્રીય નામ સ્થાપિત કર્યું" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, fuzzy, python-brace-format #| msgid "Error setting hostname: {exception}" msgid "Error setting webserver home page: {exception}" msgstr "હોસ્ટનું નામ સ્થાપિત કરતાં ભૂલ થઇ: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, fuzzy, python-brace-format #| msgid "Error setting domain name: {exception}" msgid "Error changing advanced mode: {exception}" msgstr "ક્ષેત્રીય નામ સ્થાપિત કરતાં ભૂલ થઇ: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1317,7 +1310,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as થી ઉપલબ્ધ થશે. તેનો પહેલાથી નક્કી પાસવર્ડ 'deluge' છે, પરંતુ આ સેવા સક્રિય " "કાર્ય બાદ તુરંત જ આપે લોગ ઇન કરી ને તેને બદલી નાખવો જોઈએ." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "BitTorrent કાર્યક્રમોનો ઉપયોગ કરીને ફાઇલો ડાઉનલોડ કરો" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "અનરાધાર" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "બીટ ટોરેન્ટ વેબ ક્લાયન્ટ" @@ -1537,7 +1530,7 @@ msgstr "પરિણામ" msgid "Diagnostic Test" msgstr "તપાસકીય પરિક્ષણ" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, fuzzy, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1548,7 +1541,7 @@ msgstr "" "અન્ય લોકો માટે તમને ઇન્ટરનેટ પર શોધવા માટે મુશ્કેલ હોઈ શકે છે. આ અન્ય લોકો જે આ દ્વારા " "પ્રદાન કરવામાં આવે છે તે સેવાઓ શોધવાનું અટકાવશે {box_name}" -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1565,7 +1558,7 @@ msgstr "" "પર સોંપી દેશે, અને જો ઇન્ટરનેટમાંથી કોઈ વ્યક્તિ તમારા DNS નામ માટે પૂછે, તેઓને તમારા " "વર્તમાન IP સરનામા સાથે પ્રતિસાદ મળશે." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 #, fuzzy #| msgid "" #| "If you are looking for a free dynamic DNS account, you may find a free " @@ -1584,11 +1577,11 @@ msgstr "" "net અથવા તમે મફત અપડેટ URL આધારિત સેવાઓને અહીંથી શોધી શકો છો freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "ડાયનેમિક DNS ક્લાયન્ટ" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 #, fuzzy #| msgid "Domain Name" msgid "Dynamic Domain Name" @@ -1721,7 +1714,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1782,7 +1775,7 @@ msgstr "" msgid "Already up-to-date" msgstr "છેલ્લો સુધારો" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1790,7 +1783,7 @@ msgstr "" "XMPP એક ખુલ્લું અને પ્રમાણિત સંચાર પ્રોટોકોલ છે. અહીં તમે તમારા XMPP સર્વરને ચલાવો અને " "ગોઠવી શકો છો, જેને ઈઝબેબર્ડે કહેવાય છે." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, fuzzy, python-brace-format #| msgid "" #| "To actually communicate, you can use the XMPP ક્લાયન્ટ. જ્યારે સક્ષમ કરેલ હોય, ઈઝબેબર્ડ ઍક્સેસ કરી શકાય છે " "કોઇપણ દ્વારા વપરાશકર્તાઓ સાથે{box_name}પ્રવેશ." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ઈઝબેબર્ડ" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "ચેટ સર્વર" @@ -1941,14 +1934,14 @@ msgstr "" "દેખાશે username@%(domainname)s. તમે સિસ્ટમ પર તમારા ડોમેન સેટ કરી શકો છો રૂપરેખાંકિત કરો પાનું." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1956,7 +1949,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1966,13 +1959,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2109,7 +2102,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2120,7 +2113,7 @@ msgstr "" "છે {box_name}. ફાયરવૉલ સક્ષમ અને યોગ્ય રીતે રૂપરેખાંકિત રાખીને ઇન્ટરનેટથી સુરક્ષાના ભયને " "ઘટાડે છે." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "ફાયરવોલ" @@ -2140,52 +2133,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"ફાયરવોલ ડિમન ચાલી રહ્યું નથી. કૃપા કરીને તેને ચલાવો. ફાયરવોલ %(box_name)s પર મૂળભૂત " -"સક્ષમ કરેલું છે. કોઈપણ ડેબિયન આધારિત સિસ્ટમ પર(જેવી કે %(box_name)s) તમે આદેશનો ઉપયોગ " -"કરીને તેને ચલાવી શકો છો 'service firewalld start' અથવા systemd સાથે સિસ્ટમના " -"કિસ્સામાં 'systemctl start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "સેવા/પોર્ટ" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "સક્ષમ કરેલું" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "અક્ષમ કરેલું" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "પરવાનગી છે" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "પરવાનગી છે (ફક્ત આંતરિક)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "પરવાનગી છે (બાહ્ય માત્ર)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "અવરોધિત" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2194,13 +2174,13 @@ msgstr "" "ફાયરવૉલનું સંચાલન આપોઆપ છે. જ્યારે તમે સેવાને સક્ષમ કરો છો ત્યારે તેને ફાયરવૉલમાં પણ " "પરવાનગી છે અને જ્યારે તમે કોઈ સેવા અક્ષમ કરો છો ત્યારે તે ફાયરવૉલમાં પણ અક્ષમ થાય છે." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2248,7 +2228,7 @@ msgstr "સેટઅપ પ્રારંભ કરો" msgid "Setup Complete" msgstr "સેટઅપ પૂર્ણ" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2259,83 +2239,83 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository URL." msgstr "અમાન્ય હોસ્ટનું નામ" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "અમાન્ય હોસ્ટનું નામ" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Documentation" msgid "Private repository" msgstr "દસ્તાવેજીકરણ" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Documentation" msgid "Name of the repository" msgstr "દસ્તાવેજીકરણ" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Setting unchanged" msgid "Default branch" msgstr "સેટિંગ યથાવત" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2383,19 +2363,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Documentation" msgid "Edit repository" @@ -2694,7 +2674,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2702,33 +2682,33 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy #| msgid "Enable application" msgid "Manage I2P application" msgstr "એપ્લીકેશનને પ્રસ્થાપિત કરો" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2765,14 +2745,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2781,15 +2761,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2843,41 +2823,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2885,11 +2865,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2935,7 +2915,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2953,7 +2933,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2963,7 +2943,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2971,15 +2951,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3042,41 +3022,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3086,14 +3066,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -3176,7 +3156,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3184,7 +3164,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3193,18 +3173,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3279,49 +3259,49 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 #, fuzzy #| msgid "Application installed." msgid "Public registrations enabled" msgstr "એપ્લીકેશન પ્રસ્થાપિત થઇ ગઈ છે." -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 #, fuzzy #| msgid "Application installed." msgid "Public registrations disabled" msgstr "એપ્લીકેશન પ્રસ્થાપિત થઇ ગઈ છે." -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 #, fuzzy #| msgid "Application enabled" msgid "Private mode enabled" msgstr "એપ્લિકેશન સક્ષમ કરો" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy #| msgid "Application disabled" msgid "Private mode disabled" msgstr "એપ્લિકેશન અક્ષમ છે" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 #, fuzzy #| msgid "Setting unchanged" msgid "Default skin changed" msgstr "સેટિંગ યથાવત" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "ક્ષેત્રીય નામ સ્થાપિત કર્યું" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "ક્ષેત્રીય નામ સ્થાપિત કર્યું" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3330,11 +3310,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3379,7 +3359,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3544,19 +3524,19 @@ msgstr "" msgid "Services" msgstr "સેવા પ્રકાર" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3905,7 +3885,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -4010,7 +3990,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -4026,7 +4006,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -4039,7 +4019,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4592,7 +4572,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4603,22 +4583,22 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Conversations" msgid "Connect to VPN services" msgstr "વાતચીત" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4628,61 +4608,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4691,33 +4639,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4726,87 +4674,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4840,29 +4788,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4906,8 +4854,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4949,6 +4897,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4980,7 +4959,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4991,7 +4970,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -5011,7 +4990,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5021,19 +5000,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5092,7 +5071,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -5163,7 +5142,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5176,13 +5155,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5191,31 +5170,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5293,17 +5272,17 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "ફ્રિડમબોક્ષ" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5333,51 +5312,51 @@ msgstr "એપ્લિકેશન અક્ષમ છે" msgid "Error disabling share: {error_message}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {error}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5530,14 +5509,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5546,97 +5525,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5673,26 +5652,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5700,14 +5679,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5801,7 +5780,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5849,60 +5828,60 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Last update" msgid "manually created" msgstr "છેલ્લો સુધારો" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 #, fuzzy msgid "Storage snapshots configuration updated" msgstr "DNSSEC ગોઠવણીને સુધારેલી શરુ કરો" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5910,7 +5889,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5947,14 +5926,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5967,7 +5938,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5975,145 +5946,145 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "અમાન્ય હોસ્ટનું નામ" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6147,7 +6118,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6165,30 +6136,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6196,7 +6167,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6208,20 +6179,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6230,47 +6201,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6370,13 +6341,13 @@ msgstr "ડાયનેમિક DNS સેવા" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "General Configuration" msgid "Updating configuration" msgstr "સામાન્ય ગોઠવણી" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6433,14 +6404,14 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -6451,17 +6422,17 @@ msgstr "" "સાથે{box_name} લૉગિન દ્વારા ઍક્સેસ કરી શકાય છે. સંવેદનશીલ માહિતી અને વ્યવસ્થાપનની " "ક્ષમતાઓ એડમિન ગ્રૂપના વપરાશકર્તાઓ માટે મર્યાદિત છે." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6469,12 +6440,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6482,37 +6453,37 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox Updated" msgstr "ફ્રિડમબોક્ષ" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "User registrations disabled" msgid "Distribution update started" msgstr "વપરાશકર્તા રજીસ્ટ્રેશન અક્ષમ છે" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6674,55 +6645,55 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "વપરાશકર્તા રજીસ્ટ્રેશન અક્ષમ છે" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "User registrations disabled" msgid "Distribution upgrade disabled" msgstr "વપરાશકર્તા રજીસ્ટ્રેશન અક્ષમ છે" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "User registrations disabled" msgid "Starting distribution upgrade test." msgstr "વપરાશકર્તા રજીસ્ટ્રેશન અક્ષમ છે" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6730,15 +6701,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6758,23 +6729,23 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "પાસવર્ડ બતાવો" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6783,12 +6754,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6804,41 +6775,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6855,12 +6826,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6898,17 +6869,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6939,34 +6910,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7299,7 +7270,7 @@ msgstr "ઇન્ટરનેટ સાથે સીધો જોડાણ." msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7308,7 +7279,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7317,26 +7288,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7350,7 +7321,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7363,7 +7334,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7371,11 +7342,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7427,112 +7398,108 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "એપ્લિકેશન્સ ઇન્સ્ટોલ કરો" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {string}{details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {string}{details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "એપ્લીકેશન પ્રસ્થાપિત થઇ ગઈ છે." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "છેલ્લો સુધારો" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "એપ્લિકેશન્સ ઇન્સ્ટોલ કરો" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {string}{details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "એપ્લીકેશન પ્રસ્થાપિત કરતાં ભૂલ થઇ છે: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "એપ્લીકેશન પ્રસ્થાપિત થઇ ગઈ છે." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7583,57 +7550,58 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 #, fuzzy #| msgid "BitTorrent Web Client" msgid " Apps" msgstr "બીટ ટોરેન્ટ વેબ ક્લાયન્ટ" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 #, fuzzy #| msgid "Language" msgid "Select language" msgstr "ભાષા" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -7908,6 +7876,24 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "DNSSEC ને શરુ કરો" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "ક્ષેત્રીય નામ વ્યવસ્થાની સુરક્ષા વૃદ્ધીઓ ને શરુ કરો" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "ફાયરવોલ ડિમન ચાલી રહ્યું નથી. કૃપા કરીને તેને ચલાવો. ફાયરવોલ %(box_name)s પર " +#~ "મૂળભૂત સક્ષમ કરેલું છે. કોઈપણ ડેબિયન આધારિત સિસ્ટમ પર(જેવી કે %(box_name)s) તમે આદેશનો " +#~ "ઉપયોગ કરીને તેને ચલાવી શકો છો 'service firewalld start' અથવા systemd સાથે " +#~ "સિસ્ટમના કિસ્સામાં 'systemctl start firewalld'." + #, fuzzy #~| msgid "Disabled" #~ msgid "Disable" diff --git a/plinth/locale/hi/LC_MESSAGES/django.po b/plinth/locale/hi/LC_MESSAGES/django.po index 36a6f705b..37a15efd7 100644 --- a/plinth/locale/hi/LC_MESSAGES/django.po +++ b/plinth/locale/hi/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-01-18 12:32+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Hindi calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Name of the share" msgid "Name of the new library" msgstr "शेयर का नाम" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 #, fuzzy #| msgid "A share with this name already exists." msgid "A library with this name already exists." @@ -1151,24 +1144,24 @@ msgstr "" msgid "Delete library %(library)s" msgstr "साइट हटाएं %(site)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "Archive created." msgid "Library created." msgstr "पुरालेख बनाया गया." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 #, fuzzy #| msgid "An error occurred during configuration." msgid "An error occurred while creating the library." msgstr "कॉंफ़िगरेशन के दौरान कूछ त्रुटि हुई." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} हटा गया है." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "{name} नहीं हटा गया है: {error}" @@ -1218,24 +1211,24 @@ msgstr "कॉकपिट" msgid "Server Administration" msgstr "सर्वर एडमिनिस्ट्रेशन" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "सामान्य कॉन्फ़िगरेशन" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "कॉन्फ़िगर करें" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1354,49 +1347,49 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "{exception}: होस्ट नाम सेट करने में एरर" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "होस्ट नाम सेट हो गया" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "{exception}: डोमेन नाम सेट करने में एरर" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "डोमेन नाम सेट हो गया है" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, fuzzy, python-brace-format #| msgid "Error setting hostname: {exception}" msgid "Error setting webserver home page: {exception}" msgstr "{exception}: होस्ट नाम सेट करने में एरर" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, fuzzy, python-brace-format #| msgid "Error setting domain name: {exception}" msgid "Error changing advanced mode: {exception}" msgstr "{exception}: डोमेन नाम सेट करने में एरर" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1404,7 +1397,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as freedns.afraid." "org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "डायनेमिक डिएनएस ग्राहक" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 #, fuzzy #| msgid "Domain Name" msgid "Dynamic Domain Name" @@ -1813,7 +1806,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1882,7 +1875,7 @@ msgstr "कनेक्शन हटाएँ" msgid "Already up-to-date" msgstr "अंतिम अपडेट" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1890,7 +1883,7 @@ msgstr "" "एक्सएमरपिपि एक खुला और मानकीकृत संचार प्रोटोकॉल है. यहां आप आपना एक्सएमरपिपि सर्वर " "कॉंफ़िगर आैर चल सकते हैं, सर्वर का नाम एजाबेरड है." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, fuzzy, python-brace-format #| msgid "" #| "To actually communicate, you can use the web " @@ -1908,19 +1901,19 @@ msgstr "" "ग्राहक. सक्षम होने पर एजाबेरड कोई यूसर एक {box_name} " "लोगिन से उपयोग कर सकते हैं." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "एजाबेरड" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "चाट सर्वर" @@ -2036,14 +2029,14 @@ msgstr "" "दिखेगा username@%(domainname)s. आपका डोमेन सिसटेम पर सेटअप कर सकता है कॉन्फ़िगर पेजॅ." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2051,7 +2044,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2061,13 +2054,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2210,7 +2203,7 @@ msgstr "पोर्ट" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2221,7 +2214,7 @@ msgstr "" "को नियंत्रित करता है. फ़ायरवॉल सक्षम और ठीक से कॉंफ़िगर रखते हुए इंटरनेट से सुरक्षा खतरे का " "जोखिम कम कर देता है." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "फ़ायरवॉल" @@ -2243,52 +2236,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"फ़ायरवॉल डेमन नहीं चल रहा है. इको चलिये. फ़ायरवॉल %(box_name)s पर डिफ़ॉल्ट से सक्षम " -"आता है. किसी डेबियन आधारित सिसटेम पर (%(box_name)s से तरह) आप इससे चल सकते है, 'सेवा " -"फायरवॉल शुरू' आदेश उपयेग कर या एक सिस्टमदि सिस्टम के साथ 'सिसटेमसिटिएल फायरवॉल शुरू' " -"उपयेग कर." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "सर्विस/पोर्ट" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "सक्षम किया गया है" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "अक्षम किया गया है" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "अनुमति दिया गया है" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "अनुमति दिया गया है (सिर्फ आंतरिक)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "अनुमति दिया गया है (सिर्फ बाहरी)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "अवरुद्ध" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2297,13 +2277,13 @@ msgstr "" "फ़ायरवॉल की ऑपरेशन स्वचालित है. जब आप एक सेवा सक्षम करते है, फ़ायरवॉल में भी अनुमति है और " "जब एक सेवा अक्षम करते है, फ़ायरवॉल में भी अक्षम करेगा." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2356,7 +2336,7 @@ msgstr "सटअप शुरु करें" msgid "Setup Complete" msgstr "सेटअप पूरा हो गया" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2367,75 +2347,75 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository URL." msgstr "अमान्य होस्टनाम" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "अमान्य होस्टनाम" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create User" msgid "Private repository" msgstr "यूसर बनाये" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 #, fuzzy #| msgid "A share with this name already exists." msgid "A repository with this name already exists." msgstr "इस नाम का एक शयर पहले से मौजूद है." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Name of the share" msgid "Name of the repository" msgstr "शेयर का नाम" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 #, fuzzy #| msgid "" #| "A lowercase alpha-numeric string that uniquely identifies a share. " @@ -2445,13 +2425,13 @@ msgstr "" "कोई लोअरकेस अल्फ़ा-सांख्यिक स्ट्रिंग जो विशिष्ट रूप से एक शेयर की पहचान करता है. उदाहरण:" "media." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default" msgid "Default branch" msgstr "डिफ़ॉल्ट" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2506,21 +2486,21 @@ msgstr "विकी और ब्लॉग हटाईये %(name)s%(box_name)s Wiki." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy #| msgid "Enable application" msgid "Manage I2P application" msgstr "एप्लिकेशन सक्षम करें" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "गुमनामी नेटवर्क" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 #, fuzzy #| msgid "Web Proxy" msgid "I2P Proxy" @@ -2933,7 +2913,7 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 #, fuzzy #| msgid "" #| "ikiwiki is a simple wiki and blog application. It supports several " @@ -2951,7 +2931,7 @@ msgstr "" "होने पर, ब्लॉग्स और विकि /इकिविकि/ (एक बार बनाए गए) पर " "उपलब्ध होंगे." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2964,15 +2944,15 @@ msgstr "" "विकी संपादितकर सकते है. वह युज़र कॉन्फ़िगरेशन पर " "आपको यह अनुमति बदल सकता और नया युज़रसॅ को जोडं सकता है." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "इकिविकि" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "विकि और ब्लॉग" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "विकी एप्लिकेशन को देखें और संपादित करें" @@ -3028,43 +3008,43 @@ msgstr "" "यह कार्य सब पोस्ट, पेज और टिप्पणियां निकाल देगी, संशोधन इतिहास भी. यह ब्लॉग और विकी " "हमेशा से हटा करें?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "विकी बनाया है {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "विकी नहीं बना सकता है:{error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "ब्लॉग बनाया है {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "ब्लॉग नहीं बना सकता है: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, fuzzy, python-brace-format #| msgid "{name} deleted." msgid "{title} deleted." msgstr "{name} हटा गया है." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, fuzzy, python-brace-format #| msgid "Could not delete {name}: {error}" msgid "Could not delete {title}: {error}" msgstr "{name} नहीं हटा गया है: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "इन्फिनोटेड़ गोबी के एक सर्वर है, एक सहयोगी टेक्स्ट संपादक." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3075,11 +3055,11 @@ msgstr "" "डाउनलोड और इंस्टॉल करें. फिर गोबी शुरु करें, \"सर्वर से कनेक्ट\" चुनें और {box_name} " "कर डोमेन नाम दर्ज करें." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "इन्फिनोटेड़" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "गोबी सर्वर" @@ -3125,7 +3105,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "जावास्क्रिप्ट लाइसेंस जानकारी" @@ -3145,7 +3125,7 @@ msgstr "जेएसएक्ससि" msgid "Chat Client" msgstr "चैट क्लाइंट" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3159,7 +3139,7 @@ msgstr "" "प्रमाणपत्र सेटअप प्राप्त कर सकता है. {box_name} यह लेटस एंक्रिप्ट का डोमेन का एकमात्र " "मालिक सताबित करके एेसा करता है." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3171,15 +3151,15 @@ msgstr "" "\"https://letsencrypt.org/repository/\"> लेटस एंक्रिप्ट ग्राहक समझौते इस " "सिरविस उपयोग करने से पहले." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "लेटस एंक्रिप्ट" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "प्रमाण पत्र" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3247,7 +3227,7 @@ msgstr "" "कोई डोमेन कॉंफ़िगर नहीं किया गया है. डोमेन कॉंफ़िगर करें उंहें के लिए प्रमाणपत्र प्राप्त करने के " "लिये." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3256,34 +3236,34 @@ msgstr "" "डोमेन पर प्रमाणपत्र कामयाबी सेवापस ले लिया गया{domain}. यह कुछ समय को प्रभावी करने के " "लिए ले सकता है." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "डोमेन पर प्रमाणपत्र कामयाबी से वापस नहीं ले लिया गया{domain}:{error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "डोमेन के लिए प्रमाणपत्र कामयाबी से प्राप्त किया {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "डोमेन के लिए प्रमाणपत्र कामयाबी से नहीं प्राप्त किया {domain}:{error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "डोमेन के लिए प्रमाणपत्र कामयाबी से हटाया गया {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "डोमेन के लिए प्रमाणपत्र नहीं हटाया गया {domain}:{error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3298,14 +3278,14 @@ msgstr "" "मल्टीपल डिवाइस सिंक्रनाइज़इज़ाशिन और काम करने के लिए फोन नंबर की ज़रुरत नहीं है. मैट्रिक्स " "सर्वर पर यूसरसॅ सारे मैट्रिक्स सर्वर के लेग से बात कर सकते है फ़ेडरेशिन उपयोग कर." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "मैट्रिक्स सिनापसॅ" @@ -3401,7 +3381,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3413,7 +3393,7 @@ msgstr "" "से-तरह वेबसाइट होस्ट करने के लिये, नोट्स लेने के लिये या दोस्तों के साथ प्रोजेक्ट्स पर कास कर " "सकते है." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3426,7 +3406,7 @@ msgstr "" "उपयोग करके. फिर और यूसर अकाउंट मीडियाविकी खुद ही से बना सकते है यहां जा कर Special:CreateAccountपेज." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3434,12 +3414,12 @@ msgstr "" "किसी के साथ लिंक है, वह इस विकी पढ़ सकते हैं. सिर्फ लॉगइन किए गए यूसरसॅ ही सामग्री में " "परिवर्तन कर सकते हैं." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "मीडियाविकी" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "विकी" @@ -3523,41 +3503,41 @@ msgid "Password update failed. Please choose a stronger password" msgstr "" "डेटा एंक्रिप्ट करने के लिए पासवर्ड उपयोग किया गया . सर्वर पासवर्ड से मेल खाना चाहिए." -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "सार्वजनिक रेगीसट्रेशिन सक्षम किया" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "सार्वजनिक रेगीसट्रेशिन अक्षम किया" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "निजी मोड सक्षम किया" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "निजी मोड सक्षम किया" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 #, fuzzy #| msgid "Setting unchanged" msgid "Default skin changed" msgstr "सेटिंग स्थिर है" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "डोमेन नाम सेट हो गया है" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "डोमेन नाम सेट हो गया है" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3569,11 +3549,11 @@ msgstr "" "{box_name} पर चल सकवाते है, डिफ़ॉल्ट पोर्ट (३००००) पर. सर्वर से कनेक्ट करने के लिए, एक " "मैइनटेस्ट क्लायंटकी आवश्यकता है." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "मैइनटेस्ट" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "ब्लॉक सेंडबोक्स" @@ -3620,7 +3600,7 @@ msgstr "अक्षम होने पर खिलाड़ियों न msgid "Address" msgstr "ऍड्रेस" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3801,19 +3781,19 @@ msgstr "सुरक्षित शेल" msgid "Services" msgstr "सर्विस" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "नेटवर्क्‍स" @@ -4182,7 +4162,7 @@ msgstr "कनेक्शन संपादित करें" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "संपादन" @@ -4287,7 +4267,7 @@ msgstr "आईपीवी4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "तरीका" @@ -4303,7 +4283,7 @@ msgstr "डीएनएस सर्वर" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "डिफ़ॉल्ट" @@ -4316,7 +4296,7 @@ msgid "This connection is not active." msgstr "यह कनेक्शन सक्रिय नहीं है." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "सुरक्षा" @@ -4920,7 +4900,7 @@ msgstr "कनेक्शन {name} हटाया गया." msgid "Failed to delete connection: Connection not found." msgstr "कनेक्शन हटाने में विफल: कनेक्शन नहीं मिला." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4936,22 +4916,22 @@ msgstr "" "आंतरिक सर्विसस उपयोग करने के लिये. आप बाकी सब इंटरनेट {box_name} के जरिए उपयोग कर " "सकते हैं अगर अापको और सुरक्षा और गुमनामी चाहिये." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection Type" msgid "Connect to VPN services" msgstr "कनेक्शन टाइप" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "ओपन वीपीएन" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "वर्चुअल प्राइवेट नेटवर्क" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4962,45 +4942,11 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -#, fuzzy -#| msgid "Moderate" -msgid "Migrate" -msgstr "मॉडरेट" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "प्रोफ़ाइल" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, fuzzy, python-format #| msgid "" #| "To connect to %(box_name)s's VPN, you need to download a profile and feed " @@ -5011,8 +4957,8 @@ msgstr "प्रोफ़ाइल" #| "how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "%(box_name)s का वीपीएन से कनेक्ट करने के लिए, आपको एक प्रोफ़ाइल डाउनलोड करना चाहिये " @@ -5021,16 +4967,17 @@ msgstr "" "FreedomBox/Manual/OpenVPN\" title=\"%(box_name)s Manual - OpenVPN" "\">documentation देखें अनुशंसित क्लाइंट और उन्हें कॉन्फ़िगर करने के तरीके देखने के लिये." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "प्रोफ़ाइल हर %(box_name)s यूसर के लिए विशिष्ट है. इसे गुप्त रखें." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "मेरी प्रोफ़ाइल डाउनलोड करें" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5042,17 +4989,17 @@ msgstr "" "सीधा कनेक्शन नहीं है. इसके जरूरत है सिर्फ आपके {box_name} के सर्विसस बाकी इंटरनेट से पहुँच " "योग्य नहीं. इसमें इन स्थितियों को शामिल किया गया है:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} एक प्रतिबंधित फ़ायरवॉल के पीछे है." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "{box_name} एक (वायरलेस) रूटर से कनेक्टेड है जिसे आप नियंत्रित नहीं करते हैं." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5060,7 +5007,7 @@ msgstr "" "आपका ISP आपको एक बाहरी IP एड्रेस नहीं दता लेकिन NAT के माध्यम से इंटरनेट कनेक्शन प्रदान " "करता है." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5068,11 +5015,11 @@ msgstr "" "आपके ISP आपको एक स्थिर IP एड्रेस प्रदान नहीं करता है और आपके IP एड्रेस बदलाएग जब आप " "इंटरनेट से कनेक्ट होते हैं." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "आपके ISP आने वाले कनेक्शंसस को सीमित करता है." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, fuzzy, python-brace-format #| msgid "" #| "PageKite works around NAT, firewalls and IP-address limitations by using " @@ -5091,25 +5038,25 @@ msgstr "" "pagekite.net. भविष्य में अापका दोस्त का " "{box_name} इसके लिये उपयोग कर सकते हैं." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "पेजकइट" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "सार्वजनिक विसिबिलिटी" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 #, fuzzy #| msgid "PageKite Account" msgid "PageKite Domain" msgstr "पेजकईट अकाउंट" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "सर्वर डोमेन" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5117,58 +5064,58 @@ msgstr "" "अपने पेजकईटसर्वर चूनें. \"pagekite.net\" सेट करें डिफ़ॉल्ट pagekite.net सर्वर उपयोग करने " "के लिए." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "सर्वर पोर्ट" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "अपने पेजकईट सर्वर का पोर्ट (डिफ़ॉल्ट: ८०)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "कईट नाम" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "उदाहरण: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "अमान्य कईट नाम" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "कईट गुप्त" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" "एक कोई का सम्बंधित गुप्त या अपना अकाउंट का डिफ़ॉल्ट गुप्त अगर कोई रहस्य कईट पर सेट है." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "प्रोटोकॉल" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "बाहरी (फ्रंटेंड) पोर्ट" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "आंतरिक (फ्रीडमबॉकस) पोर्ट" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "सबडोमेन सक्षम करें" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "हटाई गई कस्टम सर्विस" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 #, fuzzy #| msgid "" #| "This service is available as a standard service. Please use the " @@ -5178,11 +5125,11 @@ msgstr "" "यह सर्विस एक मानक सर्विस के रूप में उपलब्ध है. इसे सक्षम करने के लिए \"मानक सर्विस\" पेज " "का उपयोग करें." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "जोड़ा गया कस्टम सर्विस" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "यह सर्विस पहले से मौजूद है" @@ -5223,29 +5170,29 @@ msgstr "" "पोर्ट संयोजन का समर्थन नहीं कर सकते है. उदाहरण के लिए, ४४३ के अलावा पोर्ट पर HTTPS " "समस्याओं का कारण बनता है." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "वेब सर्वर (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "साइट http://{0} पर उपलब्ध होगा" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "वेब सर्वर (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "साइटhttps://{0}पर उपलब्ध होगा" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "सुरक्षित शैल (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5291,8 +5238,8 @@ msgstr "" "अभी एक स्थापना या अपग्रेड चल रहा है. इसे शट डाउन या रीस्टार्ट करने से पहले इसे समाप्त " "होने तक प्रतीक्षा करें." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "रीस्टार्ट" @@ -5343,6 +5290,39 @@ msgstr "" msgid "Shut Down Now" msgstr "अब शट डाउन करें" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "प्रिवोक्सी" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5387,7 +5367,7 @@ msgstr "वेब प्रॉक्सी" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "{url} ऐकसेस करें प्रॉक्सी लेकर {proxy} टीसीपी पर{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5403,7 +5383,7 @@ msgstr "" "ताकि आप हमेशा ऑनलाइन रखते हुए और एक या अधिक क्वासेल क्लाइंट डेस्कटॉप या मोबाइल से इसेसे " "कनेक्ट और डिस्कनेक्ट करने के लिए उपयोग किया जा सकता है." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your मोबाइल से कनेक्ट होने के लिए क्लाइंट्स उपलब्ध " "हैं." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "क्वासेल" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "आईआरसी क्लाइंट" @@ -5427,7 +5407,7 @@ msgstr "आईआरसी क्लाइंट" msgid "Quasseldroid" msgstr "क्वासेलड्रोइड" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5446,19 +5426,19 @@ msgstr "" "org/clients/\">समर्थित क्लाइंट एप्लिकेशन कि जरुरत है. राडिकैल किसी {box_name} " "यूसर पहुंचा जा सकता है एक लॉगिन के साथ." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "राडिकैल" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "कैलेंडर और पता पुस्तिका" @@ -5540,7 +5520,7 @@ msgstr "" "(जैसे http://localhost:5232) और अपने यूसरनाम दर्ज करें. खोज बटन पर क्लिक करने से मौजूदा " "कैलेंडर और पता पुस्तिकाएं सूचीबद्ध होंगी." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "ऐकसेस अधिकार कॉंफ़िगरेशन अपडेट किया गया" @@ -5634,7 +5614,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "समाचार फ़ीड्स पढ़ें और सब्सक्राइब करें" @@ -5647,13 +5627,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5662,31 +5642,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Distributed File Storage" msgid "Network File Storage" @@ -5778,19 +5758,19 @@ msgstr "शेयर जोड़ा गया." msgid "Action" msgstr "एक्सआयन" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "फ्रीडमबोएक्स" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 #, fuzzy #| msgid "Add Share" msgid "Open Share" msgstr "शेयर जोड़ें" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 #, fuzzy #| msgid "Add Share" msgid "Group Share" @@ -5826,7 +5806,7 @@ msgstr "शेयर संपादित किया गया." msgid "Error disabling share: {error_message}" msgstr "एेरर इजेक्टिग्न डिवाइस: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5834,7 +5814,7 @@ msgstr "" "सिरएक्स एक गोपनीयता संमान इंटरनेट मेटा खोज इंजन है. यह विभिन्न खोज यन्त्र से परिणाम " "इकट्ठा और प्रदर्शन करता है." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5842,39 +5822,39 @@ msgstr "" "सिरएक्स खोज इंजन द्वारा ट्रैकिंग और प्रोफाइलिंग से बचने के लिए इस्तेमाल किया जा सकता है. " "यह डिफ़ॉल्ट से कोई कुकीज़ स्टोर नहीं करता है." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "वेब सरच किजिये" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "सिरएक्स" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "वेब खोज" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "सेफ खोज" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "अपने खोज परिणामों पर अप्लाई करने के लिए डिफ़ॉल्ट परिवार फ़िल्टर चूनिये." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "मॉडरेट" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "स्ट्रिक्ट" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -6057,7 +6037,7 @@ msgstr "बुकमार्क्स" msgid "Shaarlier" msgstr "शारली" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6066,7 +6046,7 @@ msgstr "" "शैडोवॉक्स एक हल्के और सुरक्षित सॉक्स 5 प्रॉक्सी है, आपके इंटरनेट यातायात रक्षा करने के लिये. " "यह इंटरनेट फ़िल्टरिंग और सेंसरशिप बाईपास करने के लिए इस्तेमाल किया जा सकता है." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6078,7 +6058,7 @@ msgstr "" "है. यह एक सॉक्स 5 प्रॉक्सी भी चला जाएगा. स्थानीय डिवाइसस इस प्रॉक्सी से कनेक्ट कर सकते " "हैं, और उनके डेटा एंक्रिप्टेड और शैडोवॉक्स सर्वर के माध्यम से प्रॉक्सी हो जाएगा." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6086,41 +6066,41 @@ msgstr "" "सेटअप के बाद शैडोवॉक्स का उपयोग करने के लिए,अपने डिवाइस, ब्राउज़र या एप्लिकेशन में सॉक्स5 " "प्रॉक्सी यूआरएल पर सेट करें http://freedombox_address:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "शाडोसोक्स" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "सोक्स5 प्रॉक्सी" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "अनुशंसित" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "सर्वर" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "सर्वर होस्ट नाम या IP एड्रेस" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "सर्वर पोर्ट नंबर" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "डेटा एंक्रिप्ट करने के लिए पासवर्ड उपयोग किया गया . सर्वर पासवर्ड से मेल खाना चाहिए." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "एंक्रिप्शन मेथोड. सर्वर सेटिंग पर मेल खाना चाहिए." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6129,15 +6109,15 @@ msgstr "" "शेयरिंग आपको अपने {box_name} पर फ़ाइलों और फ़ोल्डरों चुना गया यूसरस के साथ वेब पर साझा " "करने की अनुमति देता है." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "शेयरिंग" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "शेयर का नाम" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6145,31 +6125,31 @@ msgstr "" "कोई लोअरकेस अल्फ़ा-सांख्यिक स्ट्रिंग जो विशिष्ट रूप से एक शेयर की पहचान करता है. उदाहरण:" "media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "शयर करने के लिए पाथ" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "इस सर्वर पर किसी फ़ोल्डर का डिस्क पाथ है जो आप साझा करना चाहते हैं." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 #, fuzzy #| msgid "Publish Key" msgid "Public share" msgstr "चाबी प्रकाशित करें" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 #, fuzzy #| msgid "User groups who can read the files in the share" msgid "User groups that can read the files in the share:" msgstr "युसर समूह जो शयर में फ़ाइलें पढ़ सकते हैं" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 #, fuzzy #| msgid "" #| "Users who have these permissions will also be able to read the files in " @@ -6179,11 +6159,11 @@ msgid "" "share." msgstr "इन अनुमतियों वाले युसरस को शयर में फ़ाइलें भी पढ़ सकते हैं." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "इस नाम का एक शयर पहले से मौजूद है." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -6220,19 +6200,19 @@ msgstr "शेयर जोड़ा गया." msgid "Add Share" msgstr "शेयर जोड़ें" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "शेयर संपादित किया गया." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "शेयर संपादित करें" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "शेयर हटाया गया." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6242,7 +6222,7 @@ msgstr "" "को वापस रोल करने के लिए इस्तेमाल किया जा सकता है, एक पहले अच्छी स्थिति ज्ञात है अगर " "सिस्टम पर अवांछित बदलाव किया गया." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6250,7 +6230,7 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 #, fuzzy #| msgid "" #| "Snapshots work on btrfs file systems only and on the root partition only. " @@ -6264,7 +6244,7 @@ msgstr "" "स्नैपशॉट्स सिर्फ btrfs फाइल सिस्टम और रूट पार्टीशन पर काम करते हैं. स्नैपशॉट बैकअप के लिए " "प्रतिस्थापन नहीं है क्योंकि वे उसी पार्टीशन पर संग्रहित होते हैं. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "स्टोरेज स्नैपशॉटस" @@ -6363,7 +6343,7 @@ msgstr "तिथि" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "स्नैपशॉटस हटाएँ" @@ -6413,61 +6393,61 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "स्नैपशॉट से रोलबैक करें #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Archive created." msgid "manually created" msgstr "पुरालेख बनाया गया." -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "स्नैपशॉटस प्रबंधित करें" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "स्नैपशॉट बनाया गया है." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "स्टोरेज स्नैपशॉट कॉंफ़िगरेशन अपडेट किया गया" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "क्रिया त्रुटि: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 #, fuzzy #| msgid "Delete all the snapshots" msgid "Deleted selected snapshots" msgstr "सब स्नैपशॉटस हटाएँ" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "स्नैपशॉट #{number} पर वापस रोलबाक होगा." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "रोलबैक शुरु करने के लिए सिस्टम रीस्टार्ट करने का ज़रुरत है." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "स्नैपशॉट को रोलबैक करें" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6478,7 +6458,7 @@ msgstr "" "स्वीकार करने के लिये. एक अधिकार दिया गया रिमोट कंप्यूटर प्रशासन कार्य निष्पादित कर " "सकता है, फ़ाइलों की कॉपी कर सकता है या ऐसे कनेक्शंस का उपयोग करके अंय सर्विसस चलाएे." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "सुरक्षित शैल (SSH) सर्वर" @@ -6517,14 +6497,6 @@ msgstr "" msgid "Fingerprint" msgstr "SSH फिंगरप्रिंट" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "एकल साइन-ऑन" @@ -6539,7 +6511,7 @@ msgstr "लॉगिन" msgid "Logged out successfully." msgstr "पासवर्ड सफलतापूर्वक बदल गया." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6547,91 +6519,91 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "स्टोरेज" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} बाइट्स" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} किब" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} मेब" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} जिब" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} टीब" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "ऑपरेशन अनुत्तीर्ण हो गया." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "ऑपरेशन रद्द किया गया." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "यह डिवाइस पहले से अनमाउट किया जा रहा है." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "यह ऑपरेशन अनुपलब्ध है क्यैकि ड्राइवर/उपकरण टूल समर्थित नहीं है." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "ऑपरेशन टाइम आउट हो गया." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "यह ऑपरेशन गहरी नींद की स्थिति का डिस्क को जाग जाएगा." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "व्यस्त डिवाइस को अनमाउंट करने का प्रयास कर रहा है." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "ऑपरेशन पहले से रद्द किया गया." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "अनुरोधित ऑपरेशन करने के लिए अधिकृत नहीं है." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "यह डिवाइस पहले से माउंट किया गया." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "यह डिवाइस नहीं माउंट किया गया." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "अनुरोधित विकल्प का उपयोग करने की अनुमति नहीं है." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "किसी और यूसर ने डिवाइस माउंट किया गया है." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, fuzzy, no-python-format, python-brace-format #| msgid "" #| "Warning: Low space on system partition ({percent_used}% used, " @@ -6641,64 +6613,64 @@ msgstr "" "वार्निंग: सिस्टम पार्टीशन पर कम जगह ({percent_used}% उपयोग किया गया, " "{free_space} free)." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "अमान्य होस्टनाम" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 #, fuzzy #| msgid "Download directory" msgid "Path is not a directory." msgstr "डायरेक्टरी डाउनलोड करें" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 #, fuzzy #| msgid "The device is mounted by another user." msgid "Directory is not readable by the user." msgstr "किसी और यूसर ने डिवाइस माउंट किया गया है." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 #, fuzzy #| msgid "Download directory" msgid "Directory" msgstr "डायरेक्टरी डाउनलोड करें" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 #, fuzzy #| msgid "Shared" msgid "Share" msgstr "साझा किया गया" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6737,7 +6709,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "रूट पारटिशन विस्तार करें" @@ -6757,30 +6729,30 @@ msgstr "" "आगे बढ़ने से पहले अपने डेटा का बैकअप करें. इस ऑपरेशन के बाद, %(expandable_root_size)s से " "अतिरिक्त खाली जगह आपके रूट पार्टीशन में उपलब्ध होगा." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "पार्टीशन का विस्तार करने में त्रुटि: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "पार्टीशन सफलतापूर्वक विस्तारित हुआ." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor}{drive_model} को सुरक्षित रूप से अनप्लग किया जा सकता है." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "डिवाइस सुरक्षित रूप से अनप्लग किया जा सकता है." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "एेरर इजेक्टिग्न डिवाइस: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6791,7 +6763,7 @@ msgstr "" "सिंक्रनाइज़ करने के लिए एक एप्लिकेशन है. सिंकतिन्ग चलते हए डिवाइसस पर किसी एक डिवाइस में " "फ़ाइलों का निर्माण, संशोधन, या हटाना ऑटोमेटिक दोहरा किया गया." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, fuzzy, python-brace-format #| msgid "" #| "Running Syncthing on {box_name} provides an extra synchronization point " @@ -6815,20 +6787,20 @@ msgstr "" "सेट एक फ़ोल्डर्स का एक अलग सेट का उपयोग करके सिंक्रनाइज़ किया जा सकता है. {box_name} " "पर वेब इंटरफेस सिर्फ \"एडमिन\" समूह के यूसकस के लिए उपलब्ध है." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "सिंकतिन्ग एप्लिकेशन का प्रशासन करें" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "सिंकतिन्ग" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "फ़ाइल सिंक्रनाइज़ेशन" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6841,7 +6813,7 @@ msgstr "" "टो प्रोजेक्ट सिफारिश की है कि आप टो ब्राउज़र उपयोग करें." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, fuzzy, python-brace-format #| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." msgid "" @@ -6849,42 +6821,42 @@ msgid "" "TCP port 9050." msgstr "एक टोर सॉक्स पोर्ट आपका %(box_name)s र उपलब्ध है, TCP पोर्ट ९०५० पर." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "टोर" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 #, fuzzy #| msgid "Tor Hidden Service" msgid "Tor Onion Service" msgstr "टोर हिडन सर्विस" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "टोर सोक्स प्रॉक्सी" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "टो ब्रिज रीले" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "टोर रीले पोर्ट उपलब्ध है" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 ट्रांसपोर्ट पंजीकृत" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 ट्रांसपोर्ट पंजीकृत" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "यूआरएल एक्सेस करें {url} टीसीपी पर {kind} टोर के माध्यम से" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "टोर उपयोग की पुष्टि करें {url} पर टीसीपी पर {kind}" @@ -7007,13 +6979,13 @@ msgstr "हिडन सर्विस" msgid "Ports" msgstr "पोर्टस" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "कॉंफ़िगरेशन के दौरान कूछ त्रुटि हुई." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -7083,7 +7055,7 @@ msgstr "" msgid "Transmission" msgstr "हस्तांतरण" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7093,7 +7065,7 @@ msgstr "" "से समाचार पढ़ने की अनुमति देने के लिए डिज़ाइन किया गया है, एक असली डेस्कटॉप एप्लिकेशन के " "जैसे." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS will be available from /" @@ -7107,7 +7079,7 @@ msgstr "" "माैजूद होते है. यह किसी एक {box_name} के सात लॉग इन " "कर सकता है." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 #, fuzzy #| msgid "" #| "When using a mobile or desktop application for Tiny Tiny RSS, use the URL " @@ -7119,11 +7091,11 @@ msgstr "" "टैनी टैनी आरएसएस का मोबाइल या डेस्कटॉप एप्लिकेशन उपयोग करते समय, यह यूआरएल/tt-rss-app कनेक्ट करने के लिए उपयोग करें." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "टिनी टिनी आरएसएस" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "समाचार फ़ीड रीडर" @@ -7131,12 +7103,12 @@ msgstr "समाचार फ़ीड रीडर" msgid "Tiny Tiny RSS (Fork)" msgstr "टैनी टैनी आरएसएस (फोर्क)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7144,8 +7116,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -7153,30 +7125,30 @@ msgstr "" msgid "Software Update" msgstr "सॉफ्टवेयर अपग्रेडस" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox Foundation" msgid "FreedomBox Updated" msgstr "फ्रीडमबाक्स फाउंडेशन" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution update started" msgstr "ऑटोमेटिक अपग्रेडस अक्षम किया गया" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7360,57 +7332,57 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "ऑटोमेटिक अपग्रेडस सक्षम किया गया" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "अनअटेंडेड-अपग्रेडस कॉन्फ़िगर करते समय त्रुटि: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "ऑटोमेटिक अपग्रेडस सक्षम किया गया" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "ऑटोमेटिक अपग्रेडस अक्षम किया गया" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Distribution upgrade enabled" msgstr "ऑटोमेटिक अपग्रेडस सक्षम किया गया" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution upgrade disabled" msgstr "ऑटोमेटिक अपग्रेडस अक्षम किया गया" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "अपग्रेड प्रक्रिया शुरू हुई." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "अपग्रेड प्रारंभ करना विफल रहा." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Starting distribution upgrade test." msgstr "ऑटोमेटिक अपग्रेडस सक्षम किया गया" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7418,15 +7390,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "यूसरस और समूह" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "सब सर्विसस और सिस्टम सेटिंग्स तक पहुंच" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "एलडीएपी प्रविष्टि चेक करें \"{search_item}\"" @@ -7446,25 +7418,25 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Password" msgid "Authorization Password" msgstr "व्यवस्थापक पासवर्ड" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "शो पासवर्ड" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 #, fuzzy #| msgid "" #| "Select which services should be available to the new user. The user will " @@ -7484,13 +7456,13 @@ msgstr "" "

एडमिन ग्रुप के यूसरस सब सर्विसस पर लॉग इन कर सकेगें. SSH के माध्यम से भी " "सिस्टम पर लॉग इन कर सकते है अाैर उनको प्रशासनिक विशेषाधिकार (sudo) है." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, fuzzy, python-brace-format #| msgid "Creating LDAP user failed." msgid "Creating LDAP user failed: {error}" msgstr "एलडीएपी यूसर बनाना विफल रहा." -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, fuzzy, python-brace-format #| msgid "Failed to add new user to {group} group." msgid "Failed to add new user to {group} group: {error}" @@ -7510,45 +7482,45 @@ msgstr "" "बिना सिस्टम में प्रवेश करने की अनुमति देगा. आप एकाधिक कीज़ दर्ज कर सकते हैं, हर लाइन रक " "एक. खाली लाइनस या # से प्रारंभ होने वाले लाइनस अनदेखा कर दिया जाएगा." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "एलडीएपी यूसर का नाम बदलना विफल रहा." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "समूह से यूसर को हटाने में विफल." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "समूह से यूसर को जोड़ने में विफल." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "एसएसएच कीज़ सेट करने में असमर्थ." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add user to group." msgid "Failed to change user status." msgstr "समूह से यूसर को जोड़ने में विफल." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "एलडीएपी यूसर का पासवर्ड बदलना विफल रहा." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, fuzzy, python-brace-format #| msgid "Failed to add new user to admin group." msgid "Failed to add new user to admin group: {error}" msgstr "व्यवस्थापक समूह में नया यूसर जोड़ने में विफल." -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, fuzzy, python-brace-format #| msgid "Failed to restrict console access." msgid "Failed to restrict console access: {error}" msgstr "कंसोल एक्सेस प्रतिबंधित करने में विफल." -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "युसर अकाउंट बनाया, अब आप लॉगड इन हैं" @@ -7565,12 +7537,12 @@ msgstr "पासवर्ड सहेजें" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "यूसर बनाये" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "यूसर हटाइये" @@ -7615,17 +7587,17 @@ msgid "The following administrator accounts exist in the system." msgstr "सिस्टम में केवल व्यवस्थापक को नहीं हटा सकता." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "यूसरस" @@ -7659,34 +7631,34 @@ msgstr "" msgid "Save Changes" msgstr "बदलाव संचयित कीजिये" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "युसर %(username)s बनाया." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "युसर %(username)s अपडेट किया." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "यूसर संपादित करें" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "यूसर {user} हटाया." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "एलडीएपी यूसरको हटाने में असफल रहा." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "पासवर्ड बदलिये" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "पासवर्ड सफलतापूर्वक बदल गया." @@ -8054,7 +8026,7 @@ msgstr "कनेक्शन हटाएँ" msgid "Server deleted." msgstr "शेयर हटाया गया." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8063,7 +8035,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8072,28 +8044,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "ऍड्रेस" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki and Blog" msgid "Website and Blog" @@ -8111,7 +8083,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8124,7 +8096,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8132,11 +8104,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -8189,114 +8161,108 @@ msgstr "" msgid "Finished: {name}" msgstr "सर्विस सक्षम किया गया:{name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing custom services" -msgid "Error running apt-get" -msgstr "मौजूदा कस्टम सर्विसस" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "इंस्टॉलिंग" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "डाउनलोडिंग" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "मीडिया बदलाव" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "कॉंफ़िगरेशन फ़ाइल: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "ऐप्लिकेशन इंस्टॉल करें" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "एप्लिकेशन नहीं इंस्टॉल जा सकता : {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "एप्लिकेशन नहीं इंस्टॉल जा सकता : {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "एप्लिकेशन नहीं इंस्टॉल जा सकता: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "एप्लिकेशन नहीं इंस्टॉल जा सकता: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "एप्लिकेशन इंस्टॉल हो गया." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "अंतिम अपडेट" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "ऐप्लिकेशन इंस्टॉल करें" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "एप्लिकेशन नहीं इंस्टॉल जा सकता : {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "एप्लिकेशन नहीं इंस्टॉल जा सकता: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "एप्लिकेशन इंस्टॉल हो गया." -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8368,54 +8334,54 @@ msgstr "इंस्टालेशन" msgid "Service %(service_name)s is not running." msgstr "सर्विस %(service_name)s नहीं चल रहा है." -#: plinth/templates/base.html:30 -#, fuzzy, python-format -#| msgid "Core funtionality and web interface for %(box_name)s" -msgid "Core functionality and web interface for %(box_name)s" -msgstr "%(box_name)s के लिए कोर फंक्शनलिटी और वेब इंटरफेस" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " होम" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "होम" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " ऐप्स" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "ऐप्स" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " सिस्टम" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "सिस्टम" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "पासवर्ड बदलें" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "शट डाउन" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "लॉग आउट" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "भाषा चुनें" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "लॉग इन" @@ -8699,6 +8665,39 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "डीएनएसएसईसि सक्षम करें" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "डॉमेन नाम सिस्टम सुरक्षा एक्सटेंशनस सक्षम करें" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "फ़ायरवॉल डेमन नहीं चल रहा है. इको चलिये. फ़ायरवॉल %(box_name)s पर डिफ़ॉल्ट से सक्षम " +#~ "आता है. किसी डेबियन आधारित सिसटेम पर (%(box_name)s से तरह) आप इससे चल सकते है, " +#~ "'सेवा फायरवॉल शुरू' आदेश उपयेग कर या एक सिस्टमदि सिस्टम के साथ 'सिसटेमसिटिएल " +#~ "फायरवॉल शुरू' उपयेग कर." + +#, fuzzy +#~| msgid "Moderate" +#~ msgid "Migrate" +#~ msgstr "मॉडरेट" + +#, fuzzy +#~| msgid "Existing custom services" +#~ msgid "Error running apt-get" +#~ msgstr "मौजूदा कस्टम सर्विसस" + +#, fuzzy, python-format +#~| msgid "Core funtionality and web interface for %(box_name)s" +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "%(box_name)s के लिए कोर फंक्शनलिटी और वेब इंटरफेस" + #~ msgid "Network Connections" #~ msgstr "नेटवर्क कनेक्शन्स" diff --git a/plinth/locale/hu/LC_MESSAGES/django.po b/plinth/locale/hu/LC_MESSAGES/django.po index 0d3948b3a..01687e9ab 100644 --- a/plinth/locale/hu/LC_MESSAGES/django.po +++ b/plinth/locale/hu/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Hungarian calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1051,23 +1044,23 @@ msgstr "" "alkalmazáshoz. Minden hozzáféréssel rendelkező felhasználó használhatja az " "összes könyvtárat." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Calibre e-könyvtárak használata" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-könyvtár" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Az új könyvtár neve" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 #, fuzzy #| msgid "" #| "Only letters of the English alphabet and numbers, without spaces or " @@ -1079,7 +1072,7 @@ msgstr "" "A könyvtár neve csak az angol ábécé betűit és számokat tartalmazhat, " "szóközök és különleges karakterek nélkül. Példa: Konyvtar_neve_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Már létezik ilyen nevű könyvtár." @@ -1127,20 +1120,20 @@ msgstr "Ugrás ebbe a könyvtárba: %(library)s" msgid "Delete library %(library)s" msgstr "%(library)s nevű könyvtár törlése" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Könyvtár létrehozva." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Hiba történt a könyvtár létrehozása közben." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} törölve." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "{name} nem törölhető: {error}" @@ -1188,7 +1181,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Szerver adminisztráció" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1196,18 +1189,18 @@ msgstr "" "Itt általános dolgokat állíthatsz be, például gazdagépnév, domainnév, " "webszerver kezdőoldala stb." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Általános beállítások" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Beállítások" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1322,47 +1315,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Hiba az állomásnév beállítása közben: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Állomásnév beállítva" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Hiba a domainnév beállítása közben: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Domainnév beállítva" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Hiba a webszerver kezdőoldalának beállítása közben: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Webszerver kezdőoldal beállítva" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Hiba a haladó módba váltás során: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Haladó szintű alkalmazások és funkciók megjelenítése" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Haladó szintű alkalmazások és funkciók elrejtése" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1374,7 +1367,7 @@ msgstr "" "más kommunikációs szerverek használhatják arra, hogy hívást hozzanak létre " "olyan felek között, akik egyébként nem tudnának kapcsolódni egymáshoz." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse vagy az ejabberd, az itt megadott részletekkel kell konfigurálni." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP-segéd" @@ -1447,11 +1440,11 @@ msgstr "Hiba az időzóna beállítása során: {exception}" msgid "Time zone set" msgstr "Időzóna beállítva" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "A Deluge egy webes felülettel rendelkező BitTorrent-kliens." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1459,16 +1452,16 @@ msgstr "" "Az alapértelmezett jelszó 'deluge', de a szolgáltatás engedélyezése után " "jelentkezz be és azonnal változtasd meg." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Fájlok letöltése BitTorrent-alkalmazások használatával" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Webes BitTorrent-kliens" @@ -1595,7 +1588,7 @@ msgstr "Eredmény" msgid "Diagnostic Test" msgstr "Ellenőrző teszt" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1607,7 +1600,7 @@ msgstr "" "Ez megakadályozza, hogy mások megtalálják a {box_name} által biztosított " "szolgáltatásokat." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1625,7 +1618,7 @@ msgstr "" "DNS-neved az új IP-címedhez, és ha valaki az Interneten lekérdezi a DNS-" "neved, válaszként az aktuális IP-címedet fogja megkapni." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1638,11 +1631,11 @@ msgstr "" "szolgáltatást a " "freedns.afraid.org címen." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Dinamikus DNS ügyfél" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dinamikus domainnév" @@ -1773,7 +1766,7 @@ msgstr "Ezt a mezőt ki kell tölteni." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1828,7 +1821,7 @@ msgstr "A szerver visszautasította a kapcsolatot" msgid "Already up-to-date" msgstr "Már frissítve" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1836,7 +1829,7 @@ msgstr "" "Az XMPP egy nyílt és szabványos kommunikációs protokoll. Itt tudod futtatni " "és konfigurálni az XMPP-szerveredet, amit ejabberd-nek neveznek." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client felhasználó számára {box_name} " "felhasználónéven." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn alkalmazást " "vagy állíts be egy külső szervert." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Chat szerver" @@ -1988,7 +1981,7 @@ msgstr "" "fognak kinézni: username@%(domainname)s. Beállíthatod a rendszered " "domainnevét a Beállítások lapon." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1999,7 +1992,7 @@ msgstr "" "lehetővé teszi az e-mail kliensek hozzáférését a leveleidhez az IMAP és POP3 " "protokollokat használva, az Rspamd pedig a kéretlen levelek szűrését végzi." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2007,7 +2000,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2023,7 +2016,7 @@ msgstr "" "álnevek, mint pl. a \"postmaster\" az első admin felhasználóhoz tartozva " "automatikusan létrejönnek az alkalmazás telepítése során." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2031,7 +2024,7 @@ msgstr "" "Roundcube alkalmazás webes felületet " "biztosít a felhasználók számára e-mail eléréséhez." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2161,7 +2154,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "Állomás/Cél/Érték" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2172,7 +2165,7 @@ msgstr "" "hálózati forgalmát felügyeli. A folyamatosan aktív és megfelelően beállított " "tűzfal csökkenti az internetről leselkedő biztonsági fenyegetések kockázatát." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Tűzfal" @@ -2192,53 +2185,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "{name} port ({details}) nem érhető el külső hálózaton" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"A Tűzfal démon nem fut. Kérlek futtasd. A Tűzfal alapértelmezetten " -"bekapcsolva érkezik a %(box_name)s eszközödre. Bármely Debian alapú " -"rendszeren (olyan mint %(box_name)s eszközöd) elindíthatod a 'service " -"firewalld start' parancs kiadásával vagy systemd alapú rendszer esetében " -"'systemctl start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Szolgáltatás/port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Engedélyezve" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Letiltva" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Engedélyezett" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Engedélyezett (csak belső)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Engedélyezett (csak külső)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Blokkolva" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2248,13 +2227,13 @@ msgstr "" "tűzfalban is engedélyezve lesz, és ha letiltod a szolgáltatást az a " "tűzfalban szintén le lesz tiltva." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Haladó" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2307,7 +2286,7 @@ msgstr "Beállítás elkezdése" msgid "Setup Complete" msgstr "Beállítás kész" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2326,7 +2305,7 @@ msgstr "" "valamelyikével. Ezek mellett megoszthatod a kódodat az emberekkel szerte a " "világon." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2335,70 +2314,70 @@ msgstr "" "href=\"https://git-scm.com/docs/gittutorial\">Git gyorstalpalót (angolul)." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Olvasási-írási hozzáférés a Git-tárolókhoz" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Egyszerű Git-hoszting" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Érvénytelen tároló URL." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Érvénytelen tárolónév." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "Az új tároló neve vagy URL egy már létező tároló importálásához." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Tároló leírása" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Opcionális, a Gitweben történő megjelenítéshez." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Tároló tulajdonosának a neve" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Privát tároló" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" "Lehetővé teszi, hogy csak az arra jogosult felhasználók férjenek hozzá ehhez " "a tárolóhoz." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Már létezik ilyen nevű tároló." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Tároló neve" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" "Olyan betűkből és számokból álló szöveg ami egyedien azonosítja a tárolót." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Alapértelmezett ág" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "A Gitweb ezt fogja alapértelmezett ágként megjeleníti." @@ -2442,19 +2421,19 @@ msgstr "%(name)s Git-tároló törlése" msgid "Delete this repository permanently?" msgstr "Véglegesen törlöd ezt a tárolót?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Tároló létrehozva." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Hiba történt a tároló létrehozása közben." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Tároló szerkesztve." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Tároló szerkesztése" @@ -2818,7 +2797,7 @@ msgstr "A {box_name} projektről" msgid "{box_name} Manual" msgstr "{box_name} kézikönyv" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2830,7 +2809,7 @@ msgstr "" "biztosít anonimitást, hogy a titkosított adatforgalmat egy világszerte " "önkéntesek által üzemeltetett hálózaton küldi keresztül." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2838,7 +2817,7 @@ msgstr "" "További információk az I2P-ről a projekt weboldalán." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2846,19 +2825,19 @@ msgstr "" "Az első látogatás a megadott webes felületen elindítja a konfigurálási " "folyamatot." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "I2P alkalmazás kezelése" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Anonim hálózat" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P proxy" @@ -2903,7 +2882,7 @@ msgstr "" "le egy peer-to-peer hálózatban. Torrentek hozzáadásával tölthetsz le " "fájlokat, vagy új torrentet hozhatsz létre egy fájl megosztásához." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2913,7 +2892,7 @@ msgstr "" "leírónyelvet támogat, beleértve a Markdown-t és olyan általános bloggolási " "funkciókat, mint például a kommentek és az RSS-hírcsatornák." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2927,15 +2906,15 @@ msgstr "" "meglévőket. A Felhasználók beállítása oldalon " "tudod módosítani ezeket a jogosultságokat vagy hozzáadni új felhasználókat." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki és blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Wiki alkalmazások megtekintése és szerkesztése" @@ -2991,42 +2970,42 @@ msgstr "" "Ez a művelet el fog távolítani minden bejegyzést, oldalt és kommentet " "beleértve a verziótörténetet is. Véglegesen törlöd ezt a wikit vagy blogot?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "{name} wiki létrehozva." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Nem sikerült létrehozni a wikit: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "{name} blog létrehozva." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Nem sikerült létrehozni a blogot: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} törölve." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "{title} nem törölhető: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" "Az infinoted egy szerver a Gobby-hoz, a kollaboratív szövegszerkesztőhöz." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3038,11 +3017,11 @@ msgstr "" "\"Csatlakozás a szerverhez\" lehetőséget (\"Connect to Server\") és írd be a " "{box_name} eszközöd domainnevét." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby-szerver" @@ -3090,7 +3069,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "JavaScript licencinformáció" @@ -3110,7 +3089,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Chat kliens" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3126,7 +3105,7 @@ msgstr "" "úgy éri el, hogy a Let's Encryptnek, egy hitelesítésszolgáltatónak (CA) " "igazolja, hogy ő a domain tulajdonosa." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3139,15 +3118,15 @@ msgstr "" "letsencrypt.org/repository/\">Let's Encrypt aláírási megállapodását " "mielőtt használnád ezt a szolgáltatást." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Tanúsítványok" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Sikertelen tesztelés: Nincsenek konfigurált domainek." @@ -3212,7 +3191,7 @@ msgstr "" "Nincsenek domainek beállítva. Előbb állítsd be a " "domaineket ahhoz, hogy tanúsítványokat kaphass hozzájuk." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3221,34 +3200,34 @@ msgstr "" "A {domain} domain tanúsítványa sikeresen visszavonva. Eltarthat néhány " "pillanatig, mire életbe lép." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "A {domain} domain tanúsítványát nem sikerült visszavonni: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "A {domain} domain sikeresen megkapta a tanúsítványt" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "A {domain} domain nem kapott tanúsítványt: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "{domain} domain tanúsítványa sikeresen törölve" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "{domain} domain tanúsítványát nem sikerült kitörölni: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3265,7 +3244,7 @@ msgstr "" "adott Matrix-szerveren lévő felhasználók föderáción keresztül " "beszélgethetnek az összes többi Matrix-szerver felhasználóival." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3275,7 +3254,7 @@ msgstr "" "videóhívásokhoz. Telepítsd a Coturn " "alkalmazást, vagy konfigurálj egy külső szervert." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3383,7 +3362,7 @@ msgstr "" "szükséged. Kérlek, látogasd meg a Let's " "Encrypt weboldalát ahhoz, hogy beszerezz egyet." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3395,7 +3374,7 @@ msgstr "" "létrehozni. A MediaWiki segítségével wikiszerű weboldalt üzemeltethetsz, " "jegyzeteket készíthetsz, vagy barátaiddal együtt dolgozhatsz projekteken." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3409,7 +3388,7 @@ msgstr "" "létrehozhatsz további felhasználói fiókokat a MediaWiki Special:CreateAccount oldalán." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3417,12 +3396,12 @@ msgstr "" "Bárki elolvashatja, akinek van hozzáférése ehhez a wikihez, viszont csak a " "bejelentkezett felhasználók módosíthatják a tartalmat." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3515,39 +3494,39 @@ msgid "Password update failed. Please choose a stronger password" msgstr "" "Az adattitkosításra használt jelszó. A szerver jelszavával meg kell egyeznie." -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Szabad regisztráció engedélyezve" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Szabad regisztráció letiltva" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Privát mód engedélyezve" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Privát mód letiltva" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Az alapértelmezett felszín megváltozott" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "Domainnév beállítva" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "Domainnév beállítva" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3561,11 +3540,11 @@ msgstr "" "szerverre egy Minetest " "kliensre is szükséged lesz." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Blokk sandbox" @@ -3614,7 +3593,7 @@ msgstr "Ha le van tiltva, a játékosok nem fognak meghalni, ill. megsérülni." msgid "Address" msgstr "Cím" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3805,7 +3784,7 @@ msgstr "Secure Shell (Biztonságos parancsértelmező)" msgid "Services" msgstr "Szolgáltatások" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3814,7 +3793,7 @@ msgstr "" "vagy PPPoE segítségével. Oszd meg ezt a kapcsolatot a hálózaton lévő más " "eszközökkel." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3822,7 +3801,7 @@ msgstr "" "Előfordulhat, hogy más módszerekkel felügyelt eszközök itt nem lesznek a " "konfigurálhatók." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Hálózatok" @@ -4258,7 +4237,7 @@ msgstr "Kapcsolat szerkesztése" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Szerkesztés" @@ -4363,7 +4342,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Módszer" @@ -4379,7 +4358,7 @@ msgstr "DNS-szerver" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Alapértelmezett" @@ -4392,7 +4371,7 @@ msgid "This connection is not active." msgstr "Ez a kapcsolat nem aktív." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Biztonság" @@ -4981,7 +4960,7 @@ msgstr "Kapcsolat törölve: {name}." msgid "Failed to delete connection: Connection not found." msgstr "A kapcsolat törlése sikertelen, mivel nem található." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4999,20 +4978,20 @@ msgstr "" "eszközödön keresztül elérheted az internetet is további biztonság és " "anonimitás érdekében." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Csatlakozás a VPN-szolgáltatásokhoz" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Virtuális magánhálózat" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5023,58 +5002,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Átállás ECC-re" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Az OpenVPN telepítése jelenleg RSA-t használ. A modern Elliptikus Görbe " -"Kriptográfiára való váltás javítja a kapcsolat létrehozásának sebességét és " -"a biztonságot. Ez a művelet visszafordíthatatlan. A legtöbb egylapos " -"számítógépen mindössze néhány percet vesz igénybe." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Az OpenVPN minden új telepítése a %(box_name)s eszközön alapértelmezés " -"szerint ECC-t fog használni. Javasoljuk a mielőbbi áttérést." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Figyelmeztetés: A meglévő kliensprofilokat ez a művelet " -"hatálytalanítja. Minden %(box_name)son lévő OpenVPN-felhasználónak le kell " -"töltenie az új profilját. A szerverhez való csatlakozáshoz az ECC-vel " -"kompatibilis OpenVPN-klienseket kell használni." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Költöztetés" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Ahhoz, hogy a %(box_name)s eszközöd virtuális magánhálózatára (VPN) " @@ -5083,18 +5025,19 @@ msgstr "" "platformra elérhetők. Kattints a fentebbi „További információk…” gombra az " "ajánlott kliensek és a beállítási utasítások megtekintéséhez." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "A profil a %(box_name)s eszköz minden egyes felhasználójára egyedi. Tartsd " "titokban." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Saját profilom letöltése" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5108,19 +5051,19 @@ msgstr "" "szolgáltatásai nem érhetők el az internet felől. Ez magában foglalja az " "alábbi eseteket:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "A {box_name} eszközöd egy korlátozott tűzfal mögött van." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "A {box_name} eszközöd egy olyan (vezeték nélküli) routerhez kapcsolódik, " "amelyet te nem állíthatsz be." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5128,7 +5071,7 @@ msgstr "" "Az internetszolgáltatód nem biztosít neked külső IP-címet, ehelyett hálózati " "címfordításon (NAT) keresztül tudod elérni az internetet." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5136,11 +5079,11 @@ msgstr "" "Az internetszolgáltatód nem biztosít neked statikus IP-címet és az IP-címed " "mindig megváltozik, amikor az internetre csatlakozol." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Az internetszolgáltatód korlátozza a bejövő kapcsolatokat." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5154,23 +5097,23 @@ msgstr "" "net. A jövőben talán a barátod {box_name} eszközét is lehetőséged lesz " "használni erre a célra." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Nyilvános láthatóság" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite domain" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Szerver domain" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5178,31 +5121,31 @@ msgstr "" "Válaszd ki a pagekite szerveredet. Állítsd „pagekite.net” -re, ha az " "alapértelmezett pagekite.net szervert szeretnéd használni." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Szerver port" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "A pagekite szervered portja (alapértelmezett: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite név" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Például: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Érvénytelen kite név" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite titkos kulcs" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5210,35 +5153,35 @@ msgstr "" "A kite-hoz kapcsolódó titkos kulcs vagy a fiókod alapértelmezett titkos " "kulcsa, ha nem lett titkos kulcs beállítva a kite-ra." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokoll" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "külső (frontend) port" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "belső (freedombox) port" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Aldomainek engedélyezése" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Törölt egyéni szolgáltatás" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Ez a szolgáltatás már elérhető szabványosként." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Egyedi szolgáltatás hozzáadva" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Ez a szolgáltatás már létezik" @@ -5276,29 +5219,29 @@ msgstr "" "HTTPS a 443-as porttól eltérő portokon történő használata közismerten " "problémákat okoz." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Webszerver (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Az oldal itt lesz elérhető: http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Webszerver (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Az oldal itt lesz elérhető: https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Biztonságos parancsértelmező (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5350,8 +5293,8 @@ msgstr "" "Jelenleg telepítés vagy frissítés zajlik. Érdemes megvárni a folyamat végét " "a leállítás vagy újraindítás előtt." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Újraindítás" @@ -5401,6 +5344,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Leállítás most" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5448,7 +5424,7 @@ msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" "Hozzáférés a {url} URL-hez {proxy} proxy használatával tcp{kind}-on keresztül" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5465,7 +5441,7 @@ msgstr "" "szolgáltatását, aminek segítségével mindig online lehetsz és egy, vagy több " "Quassel klienssel kapcsolódhatsz hozzá a mobilodról vagy az asztali gépedről." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your asztali és mobil " "eszközökhöz is." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC-kliens" @@ -5489,7 +5465,7 @@ msgstr "IRC-kliens" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5505,7 +5481,7 @@ msgstr "" "alkalmazásra is. A Radicale elérhető bármely felhasználó számára a " "{box_name} eszközön." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5515,12 +5491,12 @@ msgstr "" "címjegyzékek létrehozását támogatja. Nem támogatja az események vagy " "kapcsolatok hozzáadását, ezeket külön kliens segítségével kell elvégezni." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Naptár és címjegyzék" @@ -5593,7 +5569,7 @@ msgstr "" "és a felhasználónevet. A keresés gombra kattintva ki lesz listázva az összes " "elérhető naptár és címjegyzék." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Hozzáférési jogok beállításai frissítve" @@ -5685,7 +5661,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Hírcsatornák olvasása és feliratkozás" @@ -5698,7 +5674,7 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5706,7 +5682,7 @@ msgstr "" "A Samba lehetővé teszi a fájlok és mappák megosztását a FreedomBox és a " "helyi hálózat más számítógépei között." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5719,11 +5695,11 @@ msgstr "" "\\{hostname} (Windows alatt) vagy az smb://{hostname}.local (Linux és Mac " "alatt) címen érhetők el. Háromféle megosztás közül választhatsz: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Nyílt megosztás - a helyi hálózaton belül mindenki számára elérhető." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5731,7 +5707,7 @@ msgstr "" "Csoportos megosztás - csak a freedombox-share csoportba tartozó FreedomBox " "felhasználók számára elérhető." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5739,15 +5715,15 @@ msgstr "" "Otthoni megosztás - a freedombox-share csoport minden felhasználójának saját " "privát tárhelye lehet." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Hozzáférés a privát megosztásokhoz" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Hálózati tárhely" @@ -5836,15 +5812,15 @@ msgstr "Megosztás neve" msgid "Action" msgstr "Művelet" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS lemez" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Nyílt megosztás" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Csoport megosztás" @@ -5870,7 +5846,7 @@ msgstr "Megosztás letiltva." msgid "Error disabling share: {error_message}" msgstr "Hiba történt a megosztás letiltásakor: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5878,7 +5854,7 @@ msgstr "" "A Searx egy magánszférát tiszteletben tartó internetes metakereső. Több " "keresőmotor eredményeit gyűjti össze és jeleníti meg." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5886,41 +5862,41 @@ msgstr "" "A Searx segítségével elkerülhető, hogy a keresőmotorok nyomon kövessék és " "profilozzák a felhasználót. Sütiket eleve nem tárol." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Keresés a weben" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Webes keresés" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Biztonságos keresés" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Válaszd ki a felnőtt tartalmak alapértelmezett szűrési fokozatát, ez a " "keresési eredményeken lesz alkalmazva." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Enyhe" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Szigorú" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Nyilvános hozzáférés engedélyezése" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Engedélyezi ennek az alkalmazásnak a használatát bárkinek, aki el tudja érni." @@ -6104,7 +6080,7 @@ msgstr "Könyvjelzők" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6114,7 +6090,7 @@ msgstr "" "internetes forgalmad védelmére terveztek. Felhasználható az internetes " "szűrők és cenzúra megkerülésére." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6127,7 +6103,7 @@ msgstr "" "Helyi eszközeiddel csatlakozhatsz erre a proxy-ra, és az adataik titkosítva " "és proxizva lesznek a Shadowsocks-szerveren keresztül." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6136,41 +6112,41 @@ msgstr "" "címét a készülékeden, böngésződben vagy alkalmazásodban a http://" "freedombox_eszkozod_cime:1080/ címre" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Socks5 Proxy" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Ajánlott" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Szerver" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "A szerver állomásneve vagy IP-címe" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "A szerver portja" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Az adattitkosításra használt jelszó. A szerver jelszavával meg kell egyeznie." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Titkosítási módszer. A szerver beállításával meg kell egyeznie." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6179,15 +6155,15 @@ msgstr "" "Megosztás lehetővé teszi számodra hogy fájlokat és mappákat ossz meg a weben " "keresztül felhasználók kiválasztott csoportjaival a {box_name} eszközödön." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Megosztás" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Megosztás neve" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6195,31 +6171,31 @@ msgstr "" "Kisbetűkből és számokból álló szöveg ami egyedien azonosítja a megosztást. " "Például: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "A megosztás elérési útja" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" "Helyi elérési út a szerveren egy mappára, amelyet meg szeretnél osztani." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Nyilvános megosztás" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" "A mappában lévő fájlok elérhetővé tétele a linkkel rendelkező személyek " "számára." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" "Azok a felhasználói csoportok akik olvashatják a fájlokat a megosztásban:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6227,11 +6203,11 @@ msgstr "" "A kiválasztott felhasználói csoportok felhasználói képesek lesznek a " "megosztásban lévő fájlokat olvasni." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Egy megosztás ezzel a névvel már létezik." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" "A megosztásnak nyilvánosnak vagy legalább egy csoporttal megosztottnak kell " @@ -6270,19 +6246,19 @@ msgstr "Megosztás hozzáadva." msgid "Add Share" msgstr "Megosztás hozzáadása" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Megosztás szerkesztve." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Megosztás szerkesztése" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Megosztás törölve." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6292,7 +6268,7 @@ msgstr "" "létrehozását és kezelését. Ez akkor hasznos, ha a rendszert egy korábbi, jól " "működő állapotába szeretnéd visszaállítani egy nem kívánt változtatás után." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6304,7 +6280,7 @@ msgstr "" "pillanatképek automatikusan ki lesznek takarítva az alábbi beállítások " "szerint." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for Biztonsági mentéseket, mivel a pillanatképek csak " "ugyanazon a partíción tárolhatók, mint amelyen készülnek. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Tárhelypillanatképek" @@ -6418,7 +6394,7 @@ msgstr "Dátum" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Pillanatképek törlése" @@ -6472,59 +6448,59 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Visszaállítás erre a pillanatképre: %(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "kézzel létrehozva" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "idővonal" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Pillanatképek kezelése" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Pillanatkép létrehozva." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Tárhelypillanatképek konfigurációja frissítve" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Hiba a művelet közben: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Kiválasztott pillanatképek törölve" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" "A Tárhelypillanatképek funkció jelenleg is használatban van. Kérlek, próbáld " "újra később." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "A {number} számú pillanatképre visszaállítva." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "A visszaállítás befejezéséhez a rendszert újra kell indítani." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Visszaállítás pillanatképre" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6536,7 +6512,7 @@ msgstr "" "számítógép felügyeleti feladatokat hajthat végre, fájlokat másolhat vagy " "egyéb szolgáltatásokat futtathat ilyen kapcsolat használatával." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "SSH-szerver" @@ -6574,14 +6550,6 @@ msgstr "Algoritmus" msgid "Fingerprint" msgstr "Ujjlenyomat" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "A jelszavas SSH-hitelesítés le van tiltva." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Jelszavas SSH-hitelesítés engedélyezve." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Egyszeri bejelentkezés" @@ -6594,7 +6562,7 @@ msgstr "Bejelentkezés" msgid "Logged out successfully." msgstr "Sikeres kijelentkezés." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6606,108 +6574,108 @@ msgstr "" "fel- és lecsatolhatsz cserélhető adathordozókat, kibővítheted a root " "partíciót, stb." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Tárhely" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} byte" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "A művelet sikertelen." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "A művelet meg lett szakítva." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Az eszköz leválasztása már folyamatban van." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "A művelet nem támogatott a hiányzó illesztőprogram/eszköz támogatása miatt." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "A művelet túllépte az időkorlátot." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" "A művelet fel fogja ébreszteni a lemezt, amely mély-alvó állapotban van." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Foglalt eszköz leválasztásának a kísérlete." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "A művelet már meg lett szakítva." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Nem vagy jogosult végrehajtani a kért műveletet." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Az eszköz már fel lett csatolva." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Az eszköz nincs felcsatolva." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Nem használhatod a kért lehetőséget." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Az eszközt egy másik felhasználó felcsatolva." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Kevés a szabad hely a rendszerpartíción: {percent_used}% felhasználva, " "{free_space} szabad." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Kevés tárhely" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Lemezhiba várható" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6716,39 +6684,39 @@ msgstr "" "A {id} lemez azt jelzi, hogy a közeljövőben valószínűleg meghibásodik. " "Másold át az adatokat, amíg még lehet, és cseréld ki a meghajtót." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Érvénytelen könyvtárnév." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "A könyvtár nem létezik." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Az elérési út nem könyvtár." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "A könyvtár nem olvasható a felhasználó által." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "A felhasználónak nincs írási jogosultsága a könyvtár felett." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Könyvtár" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Alkönyvtár (opcionális)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Megosztás" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Egyéb könyvtár (add meg alább)" @@ -6785,7 +6753,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Root partíció kibővítése" @@ -6808,30 +6776,30 @@ msgstr "" "%(expandable_root_size)s további szabad tárterület lesz elérhető a root " "partíción." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Hiba a partíció kibővítése során: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "A partíció kibővítése sikerült." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} biztonságosan kivehető." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Az eszköz biztonságosan kivehető." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Hiba történt az eszköz kiadása során: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6843,7 +6811,7 @@ msgstr "" "fájljain végzett módosítások a többi eszközön is automatikusan jelentkeznek, " "amennyiben telepítve van a szolgáltatás." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6863,20 +6831,20 @@ msgstr "" "felület csak az \"admin\" vagy a \"syncthing-access\" csoporthoz tartozó " "felhasználók számára hozzáférhető." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "A Syncthing alkalmazás beállítása" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Fájlszinkronizáció" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6890,7 +6858,7 @@ msgstr "" "torproject.org/download/download-easy.html.en\">Tor böngésző használatát " "javasolja." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, fuzzy, python-brace-format #| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." msgid "" @@ -6899,40 +6867,40 @@ msgid "" msgstr "" "Egy Tor SOCKS port elérhető a %(box_name)s eszközöd 9050-es TCP-portján." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor Onion szolgáltatás" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor Socks proxy" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor híd relay" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor relay port elérhető" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 átvitel regisztrálva" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 átvitel regisztrálva" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Hozzáférés a {url} URL-hez tcp{kind}-on Tor használatával" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Hagyd jóvá a Tor használatát {url} célcímhez tcp{kind} protokollon" @@ -7053,13 +7021,13 @@ msgstr "Onion-szolgáltatás" msgid "Ports" msgstr "Portok" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Hiba történt a beállítás közben." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -7120,7 +7088,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7130,7 +7098,7 @@ msgstr "" "tervezve, hogy elérhetővé tegye a hírolvasást bárhonnan, miközben igyekszik " "egy valódi asztali alkalmazás érzetét kelteni." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS can be accessed by any felhasználó elérheti, aki {box_name} bejelentkezéssel " "rendelkezik." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7152,11 +7120,11 @@ msgstr "" "hez, használd a /tt-rss-app URL-t a " "csatlakozáshoz." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Hírcsatorna-olvasó" @@ -7164,13 +7132,13 @@ msgstr "Hírcsatorna-olvasó" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "A legfrissebb szoftver- és biztonsági frissítések ellenőrzése és alkalmazása." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7183,22 +7151,22 @@ msgstr "" "újraindítása szükségesnek bizonyul, akkor a rendszer automatikusan 02:00-kor " "újraindul, ami miatt az összes alkalmazás rövid ideig nem lesz elérhető." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Szoftverfrissítések" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox frissítve" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "A disztribúció frissítése nem tudott elindulni" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7209,11 +7177,11 @@ msgstr "" "disztribúció frissítését a rendszer 24 óra múlva újrapróbálja, ha " "engedélyezve van." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "A disztribúció frissítése elindult" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7392,46 +7360,46 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Disztribúció frissítés engedélyezve" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Hiba a nem felügyelt frissítések konfigurálása közben: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatikus frissítések engedélyezve" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatikus frissítések kikapcsolva" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Disztribúció frissítés engedélyezve" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Disztribúció frissítés letiltva" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "A frissítési folyamat elkezdődött." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "A frissítést nem sikerült elindítani." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Gyakori funkciófrissítések aktiválva." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Distribution upgrade enabled" msgid "Starting distribution upgrade test." msgstr "Disztribúció frissítés engedélyezve" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7442,7 +7410,7 @@ msgstr "" "alkalmazások megkövetelik továbbá, hogy a felhasználói fiók egy csoport " "tagja legyen, hogy a felhasználó hozzáférhessen az alkalmazáshoz." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7454,15 +7422,15 @@ msgstr "" "az admin csoport felhasználói módosíthatják az alkalmazásokat vagy " "a rendszerbeállításokat." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Felhasználók és csoportok" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Hozzáférés az összes szolgáltatáshoz és rendszerbeállításhoz" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "LDAP-bejegyzés ellenőrzése: \"{search_item}\"" @@ -7481,22 +7449,22 @@ msgid "" msgstr "" "Szükséges. Legfeljebb 150 karakter. Csak angol betűk, számjegyek és @/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Hitelesítési jelszó" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" "A fiókmódosítások engedélyezéséhez add meg \"{user}\" felhasználó jelszavát." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Érvénytelen jelszó." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7512,12 +7480,12 @@ msgstr "" "képesek bejelentkezni a rendszerbe, ahol adminisztrátori jogosultságokkal " "rendelkeznek (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "LDAP-felhasználó létrehozása sikertelen: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -7537,43 +7505,43 @@ msgstr "" "jelszó nélkül jelentkezzen be. Több kulcs is megadható; soronként egy. Az " "üres, illetve # jellel kezdődő sorok nem számítanak." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "LDAP-felhasználó átnevezése sikertelen." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Nem sikerült eltávolítani a felhasználót a csoportból." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Nem sikerült hozzáadni a felhasználót a csoporthoz." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "SSH-kulcsok beállítása sikertelen." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Nem sikerült a felhasználói állapot megváltoztatása." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "LDAP-felhasználó jelszavának megváltoztatása sikertelen." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" "Nem sikerült hozzáadni az új felhasználót a rendszergazdai csoporthoz: " "{error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Nem sikerült a konzolos hozzáférés korlátozása: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Felhasználói fiók létrehozva, bejelentkezés sikeres" @@ -7590,12 +7558,12 @@ msgstr "Jelszó mentése" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Felhasználó létrehozása" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Felhasználó törlése" @@ -7637,13 +7605,19 @@ msgid "The following administrator accounts exist in the system." msgstr "Az alábbi rendszergazdai fiókok léteznek a rendszerben." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Töröld ezeket a fiókokat a parancssorból, és frissítsd az oldalt, hogy " "létrehozz egy olyan fiókot, amely használható a %(box_name)s eszközöddel. A " @@ -7652,7 +7626,7 @@ msgstr "" "%(box_name)s eszközödön, akkor hagyd ki ezt a lépést." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Felhasználók" @@ -7685,34 +7659,34 @@ msgstr "" msgid "Save Changes" msgstr "Változtatások mentése" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "%(username)s nevű felhasználó létrehozva." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "%(username)s nevű felhasználó frissítve." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Felhasználó szerkesztése" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "{user} nevű felhasználó törölve." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "LDAP-felhasználó törlése sikertelen." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Jelszómódosítás" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "A jelszó módosítása sikeres." @@ -8049,7 +8023,7 @@ msgstr "Szerverrel létesített kapcsolat törlése" msgid "Server deleted." msgstr "Szerver törölve." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8063,7 +8037,7 @@ msgstr "" "témák segítségével választható. Az adminisztrációs felület és az előállított " "weboldalak alkalmasak a mobileszközök számára." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8077,7 +8051,7 @@ msgstr "" "futtatni. Engedélyezd a permalinkeket a rendszergazdai felületen az oldalak " "és bejegyzések jobb URL-jeihez." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8088,7 +8062,7 @@ msgstr "" "elérése érdekében mentsd el a könyvjelzőid közé az admin lapot." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8098,12 +8072,12 @@ msgstr "" "frissítését a rendszergazdai felületről. További bővítmények vagy témák " "telepítése és frissítése saját felelősségre történhet." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Weboldal és blog" @@ -8120,7 +8094,7 @@ msgstr "" "teszi lehetővé a WordPress webhely vagy blog megtekintését. Csak a WordPress " "kezdeti beállításának elvégzése után engedélyezd." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8142,7 +8116,7 @@ msgstr "" "tartózkodási hely alapján. Az egyes fényképek közvetlen link elküldésével " "megoszthatók másokkal." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8154,11 +8128,11 @@ msgstr "" "rendszerben is létre kell hozni egy-egy fiókot ugyanazzal a " "felhasználónévvel." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Fotó szervező" @@ -8213,116 +8187,110 @@ msgstr "" msgid "Finished: {name}" msgstr "Szolgáltatás letiltva: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "A(z) {package_name} a legfrissebb verzió ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Hiba történt a biztonsági mentés közben" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "telepítés" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "letöltés" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "adathordozó csere" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "konfigurációs fájl: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Alkalmazások telepítése" -#: plinth/setup.py:42 +#: plinth/setup.py:43 #, fuzzy #| msgid "Updating..." msgid "Updating app" msgstr "Frissítés…" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Hiba lépett fel az alkalmazás telepítésekor: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Hiba lépett fel az alkalmazás telepítésekor: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Hiba lépett fel az alkalmazás telepítésekor: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Hiba lépett fel az alkalmazás telepítésekor: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Alkalmazás telepítve." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Legutolsó frissítés" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Alkalmazások telepítése" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Hiba lépett fel az alkalmazás telepítésekor: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Hiba lépett fel az alkalmazás telepítésekor: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Alkalmazás telepítve." -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8383,53 +8351,54 @@ msgstr "Telepítés" msgid "Service %(service_name)s is not running." msgstr "A szolgáltatás nem fut (%(service_name)s)." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Alapvető funkcionalitás és webes felület a %(box_name)s számára" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Kezdőlap" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Kezdőlap" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Alkalmazások" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Alkalmazások" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Rendszer" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Rendszer" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Jelszómódosítás" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Leállítás" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Kijelentkezés" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Válassz nyelvet" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Bejelentkezés" @@ -8722,6 +8691,77 @@ msgstr "" msgid "Gujarati" msgstr "Gudzsaráti" +#~ msgid "Enable DNSSEC" +#~ msgstr "DNSSEC engedélyezése" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Domainnévrendszer biztonsági kiterjesztéseinek engedélyezése" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "A Tűzfal démon nem fut. Kérlek futtasd. A Tűzfal alapértelmezetten " +#~ "bekapcsolva érkezik a %(box_name)s eszközödre. Bármely Debian alapú " +#~ "rendszeren (olyan mint %(box_name)s eszközöd) elindíthatod a 'service " +#~ "firewalld start' parancs kiadásával vagy systemd alapú rendszer esetében " +#~ "'systemctl start firewalld'." + +#~ msgid "Migrate to ECC" +#~ msgstr "Átállás ECC-re" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Az OpenVPN telepítése jelenleg RSA-t használ. A modern Elliptikus Görbe " +#~ "Kriptográfiára való váltás javítja a kapcsolat létrehozásának sebességét " +#~ "és a biztonságot. Ez a művelet visszafordíthatatlan. A legtöbb egylapos " +#~ "számítógépen mindössze néhány percet vesz igénybe." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Az OpenVPN minden új telepítése a %(box_name)s eszközön alapértelmezés " +#~ "szerint ECC-t fog használni. Javasoljuk a mielőbbi áttérést." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Figyelmeztetés: A meglévő kliensprofilokat ez a művelet " +#~ "hatálytalanítja. Minden %(box_name)son lévő OpenVPN-felhasználónak le " +#~ "kell töltenie az új profilját. A szerverhez való csatlakozáshoz az ECC-" +#~ "vel kompatibilis OpenVPN-klienseket kell használni." + +#~ msgid "Migrate" +#~ msgstr "Költöztetés" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "A jelszavas SSH-hitelesítés le van tiltva." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Jelszavas SSH-hitelesítés engedélyezve." + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Hiba történt a biztonsági mentés közben" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Alapvető funkcionalitás és webes felület a %(box_name)s számára" + #~ msgid "Network Connections" #~ msgstr "Hálózati kapcsolatok" diff --git a/plinth/locale/id/LC_MESSAGES/django.po b/plinth/locale/id/LC_MESSAGES/django.po index 9b5144214..c940700b9 100644 --- a/plinth/locale/id/LC_MESSAGES/django.po +++ b/plinth/locale/id/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Indonesian (FreedomBox)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Indonesian calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1038,29 +1031,29 @@ msgstr "" "mengakses aplikasi. Semua pengguna dengan akses dapat menggunakan semua " "perpustakaan." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Gunakan perpustakaan e-book Calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "kaliber" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Perpustakaan e-book" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Nama perpustakaan baru" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Perpustakaan dengan nama ini sudah ada." @@ -1108,20 +1101,20 @@ msgstr "Pergi ke perpustakaan %(library)s" msgid "Delete library %(library)s" msgstr "Hapus perpustakaan %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Perpustakaan yang dibuat." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Terjadi kesalahan saat membuat perpustakaan." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} dihapus." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Tidak dapat menghapus {name}: {error}" @@ -1169,7 +1162,7 @@ msgstr "Kokpit" msgid "Server Administration" msgstr "Administrasi Server" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1177,18 +1170,18 @@ msgstr "" "Di sini Anda dapat mengatur beberapa opsi konfigurasi umum seperti nama " "host, nama domain, halaman beranda server web dll." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Konfigurasi Umum" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Konfigurasi" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1304,47 +1297,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Kesalahan pengaturan hostname: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Hostname set" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Kesalahan pengaturan nama domain: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Set nama domain" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Kesalahan pengaturan Webserver Halaman Beranda: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Set Halaman Rumah WebServer" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Kesalahan mengubah mode lanjutan: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Menampilkan aplikasi dan fitur canggih" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Menyembunyikan aplikasi dan fitur canggih" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1356,7 +1349,7 @@ msgstr "" "dan server komunikasi lainnya dapat menggunakannya untuk menetapkan " "panggilan antar pihak yang tidak dapat terhubung satu sama lain." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ejabberd memerlukan dikonfigurasi dengan rincian yang " "disediakan disini." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Helper VoIP" @@ -1429,11 +1422,11 @@ msgstr "Kesalahan pengaturan zona waktu: {exception}" msgid "Time zone set" msgstr "Set zona waktu" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge adalah klien BitTorrent yang menampilkan UI Web." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1441,16 +1434,16 @@ msgstr "" "Kata sandi default adalah 'Deluge', tetapi Anda harus masuk dan mengubahnya " "segera setelah mengaktifkan layanan ini." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Unduh file menggunakan aplikasi BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Membanjiri" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Klien Web BitTorrent" @@ -1578,7 +1571,7 @@ msgstr "Hasil" msgid "Diagnostic Test" msgstr "Tes Diagnostik" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1590,7 +1583,7 @@ msgstr "" "internet. Ini akan mencegah orang lain menemukan layanan yang disediakan " "oleh {box_name} ini." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1608,7 +1601,7 @@ msgstr "" "jika seseorang dari Internet meminta nama DNS Anda, mereka akan mendapatkan " "Tanggapan dengan alamat IP Anda saat ini." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 #, fuzzy #| msgid "" #| "If you are looking for a free dynamic DNS account, you may find a free " @@ -1628,11 +1621,11 @@ msgstr "" "URL pembaruan gratis di freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Klien DNS Dinamis" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Nama Domain Dinamis" @@ -1769,7 +1762,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1838,7 +1831,7 @@ msgstr "Hapus koneksi" msgid "Already up-to-date" msgstr "Automatic" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1846,7 +1839,7 @@ msgstr "" "XMPP adalah protokol komunikasi terbuka dan standar. Di sini Anda dapat " "menjalankan dan mengkonfigurasi server XMPP Anda, yang disebut Ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientKlien XMPP. Saat diaktifkan, ejabberd dapat diakses " "oleh pengguna dengan sebuah {box_name} login." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn atau konfigurasikan server " "eksternal." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "Ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Server obrolan" @@ -1992,14 +1985,14 @@ msgstr "" "terlihat seperti nama pengguna @%(domainname)s. Anda dapat mengatur " "domain Anda pada sistem Konfigurasi halaman." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2007,7 +2000,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2017,13 +2010,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2166,7 +2159,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2177,7 +2170,7 @@ msgstr "" "masuk dan keluar pada {box_name} Anda. Menjaga firewall diaktifkan dan " "dikonfigurasi dengan benar mengurangi risiko ancaman keamanan dari Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2197,53 +2190,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} ({details}) tidak tersedia untuk jaringan eksternal" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Daemon firewall tidak berjalan. Silakan jalankan. Firewall datang diaktifkan " -"secara default pada %(box_name)s. Pada sistem berbasis debian apa pun " -"(seperti %(box_name)s) Anda dapat menjalankannya menggunakan perintah " -"'Service firewalld start' atau Dalam hal sistem dengan systemd 'systemctl " -"mulai firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Layanan/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Aktifkan" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Non-Aktifkan" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Diizinkan" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Diizinkan (hanya internal)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Diizinkan (hanya eksternal)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Diblokir" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2253,13 +2232,13 @@ msgstr "" "diizinkan di firewall dan ketika Anda menonaktifkan layanan, itu juga " "dinonaktifkan di firewall." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Maju" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2312,7 +2291,7 @@ msgstr "Jalankan Pengaturan" msgid "Setup Complete" msgstr "Pengaturan Selesai" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2330,7 +2309,7 @@ msgstr "" "beberapa klien grafis yang tersedia. Dan Anda dapat membagikan kode Anda " "dengan orang-orang di seluruh dunia." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2338,67 +2317,67 @@ msgstr "" "Untuk mempelajari lebih lanjut tentang cara menggunakan git kunjungi tutorial git ." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Akses baca-tulis ke repositori git" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Hosting Git Sederhana" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "URL repositori tidak valid." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Nama repositori tidak valid." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "Nama repositori atau URL baru untuk mengimpor repositori yang ada." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Deskripsi repositori" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Opsional, untuk ditampilkan di Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Nama pemilik repositori" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Penyimpanan Pribadi" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Berikan hanya pengguna yang berwenang untuk mengakses repositori ini." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Sebuah repositori dengan nama ini sudah ada." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Nama repositori" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "String alfa-numerik yang secara unik mengidentifikasi repositori." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Cabang default" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb menampilkan ini sebagai cabang default." @@ -2442,19 +2421,19 @@ msgstr "Hapus git repositori %(name)s " msgid "Delete this repository permanently?" msgstr "Hapus repositori ini secara permanen?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Repositori dibuat." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Terjadi kesalahan saat membuat repositori." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Diedit repositori." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Edit Repositori" @@ -2813,7 +2792,7 @@ msgstr "Tentang {box_name}" msgid "{box_name} Manual" msgstr "Panduan {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2825,7 +2804,7 @@ msgstr "" "memberikan anonimitas dengan mengirimkan lalu lintas terenkripsi melalui " "jaringan yang dikelola sukarela yang didistribusikan di seluruh dunia." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2833,7 +2812,7 @@ msgstr "" "Temukan informasi lebih lanjut tentang i2p pada proyek mereka, Halaman Beranda." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2841,19 +2820,19 @@ msgstr "" "Kunjungan pertama ke antarmuka web yang disediakan akan memulai proses " "konfigurasi." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Kelola aplikasi I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2p" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Jaringan Anonimitas" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2p proxy" @@ -2903,7 +2882,7 @@ msgstr "" "to-peer. Unduh file dengan menambahkan torrents atau buat torrent baru untuk " "berbagi file." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2913,7 +2892,7 @@ msgstr "" "bahasa markup ringan, termasuk Markdown, dan fungsionalitas blogging umum " "seperti komentar dan umpan RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2927,15 +2906,15 @@ msgstr "" "\"{users_url}\">Konfigurasi Pengguna, Anda dapat mengubah izin ini atau " "menambahkan pengguna baru." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "Ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki dan Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Lihat dan edit aplikasi Wiki" @@ -2991,41 +2970,41 @@ msgstr "" "Tindakan ini akan menghapus semua posting, halaman, dan komentar termasuk " "riwayat revisi. Hapus wiki atau blog ini secara permanen?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Membuat wiki {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Tidak dapat membuat wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "membuat blog {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Tidak dapat membuat blog: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} dihapus." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Tidak dapat menghapus {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "Infinoted adalah server untuk gobby, editor teks kolaboratif." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3036,11 +3015,11 @@ msgstr "" "a>, desktop client dan instal. Kemudian mulai gobby dan pilih \"Hubungkan ke " "Server\" dan masukkan nama domain {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "Menginfisi" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Server Gobby" @@ -3088,7 +3067,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Informasi Lisensi JavaScript" @@ -3108,7 +3087,7 @@ msgstr "Jsxc" msgid "Chat Client" msgstr "Obrolan Klien" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3124,7 +3103,7 @@ msgstr "" "pengguna adalah pemilik sebuah domain ke Let's Encrypt, sebuah otoritas " "sertifikat (CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3137,15 +3116,15 @@ msgstr "" "repository/\">Perjanjian Pelanggan Let's Encrypt sebelum menggunakan " "layanan ini." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Sertifikat" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Tidak dapat menguji: Tidak ada domain yang dikonfigurasi." @@ -3210,7 +3189,7 @@ msgstr "" "Tidak ada domain yang dikonfigurasi. " "mengkonfigurasi domain untuk dapat memperoleh sertifikat untuk mereka." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3219,34 +3198,34 @@ msgstr "" "Sertifikat berhasil dicabut untuk domain {domain}. Ini mungkin memakan waktu " "beberapa saat untuk mulai berlaku." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Gagal mencabut sertifikat untuk domain {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Sertifikat berhasil diperoleh untuk domain {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Gagal memperoleh sertifikat untuk domain {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Sertifikat berhasil dihapus untuk domain {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Gagal menghapus sertifikat untuk domain {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3263,7 +3242,7 @@ msgstr "" "Pengguna pada server matriks tertentu dapat berkomunikasi dengan pengguna di " "semua server matriks lainnya melalui Federation." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3273,7 +3252,7 @@ msgstr "" "Pasang aplikasi Coturn atau konfigurasikan " "server eksternal." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Sinaps Matrix" @@ -3360,7 +3339,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3368,7 +3347,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3377,18 +3356,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3463,39 +3442,39 @@ msgstr "" "Kata sandi yang digunakan untuk mengenkripsi data. Harus mencocokkan kata " "sandi server." -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Pendaftaran publik diaktifkan" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Pendaftaran publik dinonaktifkan" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Mode privat diaktifkan" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Mode privat dinonaktifkan" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "Set nama domain" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "Set nama domain" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3504,11 +3483,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3553,7 +3532,7 @@ msgstr "" msgid "Address" msgstr "Address" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3714,19 +3693,19 @@ msgstr "Secure Shell" msgid "Services" msgstr "Layanan" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Jaringan" @@ -4072,7 +4051,7 @@ msgstr "Sunting Koneksi" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Sunting" @@ -4177,7 +4156,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -4193,7 +4172,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -4206,7 +4185,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4742,7 +4721,7 @@ msgstr "Koneksi {name} dihapus." msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4753,20 +4732,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Sambungkan ke layanan VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Jaringan Privat Virtual" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4776,61 +4755,29 @@ msgstr "Unduh Profil" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Migrasi ke ECC" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migrasi" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Unduh profil saya" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4839,33 +4786,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "ISP Anda membatasi koneksi masuk." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4874,87 +4821,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Visibilitas Publik" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Domain PageKite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Domain peladen" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Port Peladen" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "nama Kite" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Contoh: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokol" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Aktifkan Subdomain" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "layanan kustom yang dihapus" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4990,29 +4937,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Server Web (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Situs akan tersedia di http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Web Server (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5056,8 +5003,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Mulai ulang" @@ -5099,6 +5046,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Matikan Sekarang" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5130,7 +5110,7 @@ msgstr "Proksi Web" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Akses {url} dengan proksi {proxy} pada tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5141,7 +5121,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Klien IRC" @@ -5161,7 +5141,7 @@ msgstr "Klien IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5171,19 +5151,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5242,7 +5222,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -5314,7 +5294,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5327,13 +5307,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5342,31 +5322,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Penyimpanan Berkas Jaringan" @@ -5448,19 +5428,19 @@ msgstr "Shared" msgid "Action" msgstr "Aksi" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 #, fuzzy #| msgid "Add Service" msgid "Open Share" msgstr "Tambah Layanan" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 #, fuzzy #| msgid "Add Service" msgid "Group Share" @@ -5490,51 +5470,51 @@ msgstr "Bagikan dinonaktifkan." msgid "Error disabling share: {error_message}" msgstr "Kesalahan pemasangan aplikasi: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Jelajahi web" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Pencarian Web" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Pencarian Aman" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Moderat" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Ketat" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5691,14 +5671,14 @@ msgstr "Bookmark" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5707,99 +5687,99 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Proksi Socks5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Disarankan" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Peladen" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Alamat IP atau hostname Peladen" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Nomor port peladen" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Kata sandi yang digunakan untuk mengenkripsi data. Harus mencocokkan kata " "sandi server." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Metode enkripsi. Harus mencocokkan setelan pada peladen." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Berbagi" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Nama pembagian" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Jalur untuk berbagi" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Bagikan publik" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5836,26 +5816,26 @@ msgstr "Bagikan ditambahkan." msgid "Add Share" msgstr "Tambah Bagikan" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Bagikan diedit." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Sunting Bagikan" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Bagikan dihapus." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5863,14 +5843,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Penyimpanan Snapshot" @@ -5972,7 +5952,7 @@ msgstr "Tanggal" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Hapus Snapshot" @@ -6020,57 +6000,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "dibuat manual" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "linimasa" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Kelola Snapshot" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Snapshot yang dibuat." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Konfigurasi snapshot penyimpanan diperbarui" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Galat {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Menghapus snapshot yang dipilih" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Snapshot sedang digunakan. Silakan coba lagi nanti." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Sistem harus dimulai ulang untuk menyelesaikan rollback." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Rollback ke Snapshot" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6078,7 +6058,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Server Secure Shell (SSH)" @@ -6115,14 +6095,6 @@ msgstr "Algoritma" msgid "Fingerprint" msgstr "Sidik Jari" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6135,7 +6107,7 @@ msgstr "Masuk" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6143,143 +6115,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Penyimpanan" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bytes" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Operasi gagal." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Operasi telah dibatalkan." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Perangkat belum terpasang." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Nama direktori tidak valid." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Direktori ini tidak ada." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Direktori" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Subdirektori (opsional)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Bagikan" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Direktori lainnya (silakan tulis)" @@ -6313,7 +6285,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6331,30 +6303,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6362,7 +6334,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6374,20 +6346,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6396,47 +6368,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6538,13 +6510,13 @@ msgstr "Layanan" msgid "Ports" msgstr "Port" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Terjadi kesalahan selama konfigurasi." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6602,14 +6574,14 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "It can be accessed by any user on {box_name} " @@ -6621,17 +6593,17 @@ msgstr "" "Itu dapat diakses oleh pengguna apa pun pada " "{box_name} milik kelompok admin." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6640,12 +6612,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6653,8 +6625,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -6662,28 +6634,28 @@ msgstr "" msgid "Software Update" msgstr "URL Server diperbarui" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox Updated" msgstr "FreedomBox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Pembaruan distribusi dimulai" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6847,53 +6819,53 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Pembaruan distribusi dinonaktifkan" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Pembaruan distribusi dinonaktifkan" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Distribution upgrade disabled" msgid "Starting distribution upgrade test." msgstr "Pembaruan distribusi dinonaktifkan" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6901,15 +6873,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6927,23 +6899,23 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Account" msgid "Authorization Password" msgstr "Akun Administrator" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Kata sandi tidak valid." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6952,12 +6924,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Gagal membuat pengguna LDAP. {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Gagal menambahkan pengguna baru ke kelompok {group}: {error}" @@ -6973,43 +6945,43 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add new user to admin group." msgid "Failed to change user status." msgstr "Gagal menambahkan pengguna baru ke kelompok admin." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Gagal menambahkan pengguna baru ke kelompok admin. {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -7026,12 +6998,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -7071,17 +7043,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -7112,34 +7084,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Insan {user} dipangkar." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7466,7 +7438,7 @@ msgstr "Hapus Koneksi" msgid "Server deleted." msgstr "{name} dihapus." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7475,7 +7447,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7484,28 +7456,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "Address" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki and Blog" msgid "Website and Blog" @@ -7523,7 +7495,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7536,7 +7508,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7544,11 +7516,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7598,114 +7570,108 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Kesalahan saat cadangan" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "memasang" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "mengunduh" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Instal aplikasi" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Kesalahan Pemasangan aplikasi: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Kesalahan Pemasangan aplikasi: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Kesalahan pemasangan aplikasi: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Kesalahan pemasangan aplikasi: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Aplikasi telah terpasang." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Pembaharuan Terakhir" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Instal aplikasi" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Kesalahan Pemasangan aplikasi: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Kesalahan pemasangan aplikasi: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Aplikasi telah terpasang." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7757,53 +7723,54 @@ msgstr "Pemasangan" msgid "Service %(service_name)s is not running." msgstr "Layanan %(service_name)s tidak berjalan." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Fungsionalitas inti dan antarmuka web untuk %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Beranda" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Beranda" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Aplikasi" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Apps" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " sistem" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Sistem" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Ganti kata sandi" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Matikan" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Keluar" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Pilih bahasa" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Masuk" @@ -8074,6 +8041,40 @@ msgstr "" msgid "Gujarati" msgstr "Bahasa Gujarat" +#~ msgid "Enable DNSSEC" +#~ msgstr "Aktifkan DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Aktifkan ekstensi keamanan nama domain" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Daemon firewall tidak berjalan. Silakan jalankan. Firewall datang " +#~ "diaktifkan secara default pada %(box_name)s. Pada sistem berbasis debian " +#~ "apa pun (seperti %(box_name)s) Anda dapat menjalankannya menggunakan " +#~ "perintah 'Service firewalld start' atau Dalam hal sistem dengan systemd " +#~ "'systemctl mulai firewalld'." + +#~ msgid "Migrate to ECC" +#~ msgstr "Migrasi ke ECC" + +#~ msgid "Migrate" +#~ msgstr "Migrasi" + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Kesalahan saat cadangan" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Fungsionalitas inti dan antarmuka web untuk %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Koneksi Jaringan" diff --git a/plinth/locale/it/LC_MESSAGES/django.po b/plinth/locale/it/LC_MESSAGES/django.po index 5bbac2b3c..6f90faf0e 100644 --- a/plinth/locale/it/LC_MESSAGES/django.po +++ b/plinth/locale/it/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Italian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Nome della nuova libreria" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Esiste già una libreria con questo nome." @@ -1094,20 +1087,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "Cancella libreria %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Libreria creata." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Si è verificato un errore durante la creazione della libreria." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} cancellato." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Non è stato possibile cancellare {name}: {error}" @@ -1152,7 +1145,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Amministrazione Server" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1160,18 +1153,18 @@ msgstr "" "Qui si possono impostare alcune opzioni di configurazione generali come " "hostname, nome di dominio, home page del webserver ecc." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Configurazione Generale" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Configura" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1292,50 +1285,50 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Errore impostazione hostname: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 #, fuzzy msgid "Hostname set" msgstr "Imposta hostname" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Errore impostazione nome di dominio: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 #, fuzzy msgid "Domain name set" msgstr "Imposta nome di dominio" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Errore impostazione home page server web: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 #, fuzzy msgid "Webserver home page set" msgstr "Impostato home page del webserver" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Errore nel cambio di modalità avanzata: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Visualizzazione di applicazioni e funzionalità avanzate" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Nascondere applicazioni e funzionalità avanzate" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1343,7 +1336,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Client DNS Dinamico" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Nome Dominio Dinamico" @@ -1743,7 +1736,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1813,7 +1806,7 @@ msgstr "Cancella connessione" msgid "Already up-to-date" msgstr "Abilita l'aggiornamento automatico" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1821,7 +1814,7 @@ msgstr "" "XMPP è un protocollo di comunicazione aperto e standardizzato. Qui puoi " "eseguire e configurare il tuo server XMPP, chiamato ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client da ogni utente con un login " "{box_name} ." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Server Chat" @@ -1967,14 +1960,14 @@ msgstr "" "impostare il tuo dominio nel sistema . Configura " "la pagina ." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1982,7 +1975,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1992,13 +1985,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2127,7 +2120,7 @@ msgstr "Porta" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2139,7 +2132,7 @@ msgstr "" "adeguatamente configurato riduce i rischi di attacchi informatici dalla rete " "Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2159,53 +2152,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Porta {name} ({details}) non disponibile per reti esterne" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Il demone del firewall non è in esecuzione. Abilitalo per favore. Il " -"firewall è attivato di predefinito nel %(box_name)s. Sui qualsiasi sistema " -"basato su Debian (come %(box_name)s) è possibile eseguirlo usando il comando " -"'service firewall start' o nol caso di un sistema con systemd 'systemctl " -"start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Servizio/Porta" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Abilitato" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Disabilitato" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Permesso" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Permesso (solo internamente)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Permesso (solo esternamente)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Bloccato" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2215,13 +2194,13 @@ msgstr "" "abilitato anche sul firewall, e quando lo disabiliti, viene disabilitato " "anche nel firewall." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2272,7 +2251,7 @@ msgstr "Avvia Configurazione" msgid "Setup Complete" msgstr "Configurazione Completata" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2291,7 +2270,7 @@ msgstr "" "grafici disponibili. E puoi condividere il tuo codice con persone in tutto " "il mondo." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2299,71 +2278,71 @@ msgstr "" "Per saperne di più su come usare Git visita Git tutorial." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Accesso in lettura e scrittura ai repository Git" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Semplice Git Hosting" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "URL del repository non valido." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Nome del deposito non valido." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Nome di un nuovo repository o URL per importare un repository esistente." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Descrizione del repository" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Opzionale, per la visualizzazione su Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Nome del proprietario del deposito" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Deposito privato" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Consentire l'accesso a questo repository solo agli utenti autorizzati." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Esiste già un deposito con questo nome." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Nome del deposito" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 #, fuzzy msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Una stringa alfanumerica che identifica in modo univoco un deposito." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default" msgid "Default branch" msgstr "Ramo di default" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2407,19 +2386,19 @@ msgstr "Cancellare Git Repository %(name)s" msgid "Delete this repository permanently?" msgstr "Cancellare questo repository in modo permanente?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Repository creato." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Si è verificato un errore durante la creazione del repository." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Repository modificato." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Modifica repository" @@ -2789,7 +2768,7 @@ msgstr "Sul {box_name}" msgid "{box_name} Manual" msgstr "Manuale {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 #, fuzzy msgid "" "The Invisible Internet Project is an anonymous network layer intended to " @@ -2802,7 +2781,7 @@ msgstr "" "l'anonimato inviando traffico criptato attraverso una rete di volontari " "distribuiti in tutto il mondo." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2810,7 +2789,7 @@ msgstr "" "Si possono trovare maggiori informazioni su I2P sul sito web del loro progetto." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 #, fuzzy msgid "" "The first visit to the provided web interface will initiate the " @@ -2819,20 +2798,20 @@ msgstr "" "La prima visita all'interfaccia web fornita inizierà il processo di " "configurazione." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Gestione dell'applicazione I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 #, fuzzy msgid "Anonymity Network" msgstr "Rete di anonimato" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "Proxy I2P" @@ -2880,7 +2859,7 @@ msgstr "" "peer-to-peer. Scaricate i file aggiungendo torrenti o create un nuovo " "torrent per condividere un file." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2890,7 +2869,7 @@ msgstr "" "markup di linguaggio leggeri, incluso Markdown, e comuni funzionalità di " "blogging come commenti e feed RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2904,15 +2883,15 @@ msgstr "" "\"{users_url}\">Configurazione Utente è possibile cambiare questi " "permessi o aggiungere nuovi utenti." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki e Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Vedi e modifica le applicazioni wiki" @@ -2968,42 +2947,42 @@ msgstr "" "Quest'azione cancellerà tutti i post, le pagine e i commenti, incluse le " "revisione storiche. Cancellare questo wiki o blog permanentente?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Creato wiki {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Non è stato possibile creare l'wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Creato blog {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Non è stato possibile creare il blog: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} cancellato." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Non è stato possibile cancellare {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 #, fuzzy msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted è un server per Gobby, un editore testuale comunitario." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, fuzzy, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3014,11 +2993,11 @@ msgstr "" "desktop e installarlo. Dopo avviare Hobby e seleziona \"Connect to Server\" " "e entrare nel tuo nome di dominio {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby Server" @@ -3066,7 +3045,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Informazioni sulla licenza JavaScript" @@ -3086,7 +3065,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Client" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3101,7 +3080,7 @@ msgstr "" "disposizione. Ci riesce provando esso stesso di essere il proprietario del " "dominio a Let's Encrypt, un'autorità di certificazione (CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3114,15 +3093,15 @@ msgstr "" "letsencrypt.org/repository/\"> i termini dell'accordo dell'abbonato Let's " "Encrypt prima utilizzare questo servizio." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certificati" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3187,7 +3166,7 @@ msgstr "" "Non sono stati configurati domini. Configurare i " "domini per poter ottenere i certificati per essi." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3196,34 +3175,34 @@ msgstr "" "Certificato revocato correttamente per il dominio {domain}. Ciò può " "richiedere alcuni minuti per avere effetto." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Revoca certificato fallita per il dominio {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Certificato correttamente ottenuto per il dominio {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Rilascio certificato fallito per il dominio {domain}:{error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Certificato cancellato correttamente per il dominio {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Cancellazione certificato fallita per il dominio {domain}:{error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3240,14 +3219,14 @@ msgstr "" "Gli utenti di un certo server Matrix possono comunicare con gli altri utenti " "attestati su tutti gli altri server Matrix tramite federazione." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3349,7 +3328,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3362,7 +3341,7 @@ msgstr "" "stile wiki, per prendere note o per collaborare con degli amici su dei " "progetti." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3377,7 +3356,7 @@ msgstr "" "MediaWiki, andando nella pagina Speciale:CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3385,12 +3364,12 @@ msgstr "" "Chiunque con un collegamento a questo wiki può leggerlo. Solo gli utenti " "autenticati possono apportare modifiche ai contenuti." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3472,39 +3451,39 @@ msgstr "Password aggiornata" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Registrazioni pubbliche abilitate" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Registrazioni pubbliche disabilitate" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 #, fuzzy msgid "Private mode enabled" msgstr "Modo privato abilitato" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy msgid "Private mode disabled" msgstr "Modo privato disabilitato" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Tema predefinito modificato" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy msgid "Domain name updated" msgstr "Imposta nome di dominio" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy msgid "Site name updated" msgstr "Imposta nome di dominio" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3517,11 +3496,11 @@ msgstr "" "porta predefinita (30000). Per connettersi al server, è necessario un client Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Block Sandbox" @@ -3575,7 +3554,7 @@ msgstr "" msgid "Address" msgstr "Indirizzo" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3752,19 +3731,19 @@ msgstr "Secure Shell" msgid "Services" msgstr "Servizi" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Reti" @@ -4134,7 +4113,7 @@ msgstr "Modifica Connessione" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Modifica" @@ -4240,7 +4219,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Metodo" @@ -4256,7 +4235,7 @@ msgstr "Server DNS" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Default" @@ -4269,7 +4248,7 @@ msgid "This connection is not active." msgstr "Questa connessione non è attiva." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Sicurezza" @@ -4814,7 +4793,7 @@ msgstr "Connessione {name} cancellata." msgid "Failed to delete connection: Connection not found." msgstr "Cancellazione connessione fallita: connessione non trovata." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4831,20 +4810,20 @@ msgstr "" "accedere al resto della rete Internet via {box_name} per una maggiore " "sicurezza e anonimità." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Rete virtuale privata" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4855,48 +4834,21 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profilo" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Per connetterti alla VPN del %(box_name)s, hai bisogno di scaricare un " @@ -4905,17 +4857,18 @@ msgstr "" "Cliccate su \"Per saperne di più...\" qui sopra per i clienti consigliati e " "le istruzioni su come configurarli." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Il profilo è specifico per ogni utente del %(box_name)s. Mantienilo segreto." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Scarica il mio profilo" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4928,18 +4881,18 @@ msgstr "" "il tuo {box_name} non è raggiungibile dall'esterno. Questo include le " "situazioni seguenti:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} è valle di un firewall ristretto." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} è connesso ad un router (wireless) di cui non hai il controllo." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -4947,7 +4900,7 @@ msgstr "" "Il tuo ISP non ti assegna un IP pubblico ma ti fornisce una connessione " "tramite NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -4955,11 +4908,11 @@ msgstr "" "Il tuo ISP non ti fornisce un IP statico e il tuo IP cambia ogni volta che " "ti connetti a Internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Il tuo ISP limita le connessioni in entrata." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4973,23 +4926,23 @@ msgstr "" "futuro potrebbe essere possibile usare la {box_name} del tuo amico per " "questo." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Visibilità Pubblica" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Dominio PageKite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Dominio server" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -4997,31 +4950,31 @@ msgstr "" "Selezione il tuo server pagekite. Imposta \"pagekite.net\" per usare il " "server predefinito di pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Porta server" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Porta del tuo server pagekite (predefinita: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Nome Kite" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Esempio: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Nome Kite invalido" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Segreto Kite" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5029,35 +4982,35 @@ msgstr "" "Un segreto associate col kite o il segreto predefinito del tuo profile nel " "caso non sia state impostato nel kite." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protocollo" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "porta esterna (frontend)" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "porta interna (freedombox)" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Abilita Sottodomini" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Cancella servizio personalizzato" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Questo servizio è già disponibile come servizio standard." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Servizio personalizzato aggiunto" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Questo servizio è già presente" @@ -5095,29 +5048,29 @@ msgstr "" "Per esempio, è noto che HTTPS, in porte diverse dalla 443, può causare " "problemi." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Server Web (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Il sito sarà disponibile su http{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Server Web (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Il sito sarà disponibile au HTTPS://{0}{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5164,8 +5117,8 @@ msgstr "" "la possibilità di aspettare che fimisca prima di spegnere o riavviare il " "sistema." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -5216,6 +5169,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Spegni Ora" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5262,7 +5248,7 @@ msgstr "Web Proxy" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Accesso {url} con proxy {proxy} su tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5279,7 +5265,7 @@ msgstr "" "possibile usare uno o più client Quassel desktop o mobile, per connettersi e " "disconnettersi su di esso." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your desktop e mobile." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Client IRC" @@ -5303,7 +5289,7 @@ msgstr "Client IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5318,19 +5304,19 @@ msgstr "" "un'applicazione client supportata. È possibile accedere a Radicale da " "ogni utente con un profilo {box_name}." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Calendario e Rubrica" @@ -5398,7 +5384,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -5470,7 +5456,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5483,13 +5469,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5498,31 +5484,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Stoccaggio dei file di rete" @@ -5600,15 +5586,15 @@ msgstr "Nome Share" msgid "Action" msgstr "Azione" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Apri Share" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5634,51 +5620,51 @@ msgstr "Share disabilitato." msgid "Error disabling share: {error_message}" msgstr "Errore installazione applicazione: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5833,14 +5819,14 @@ msgstr "" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5849,97 +5835,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Share pubblico" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5976,26 +5962,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6003,14 +5989,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -6104,7 +6090,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -6152,58 +6138,58 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "creato manualmente" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 #, fuzzy msgid "Deleted selected snapshots" msgstr "Istantanee selezionate cancellate" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6211,7 +6197,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -6244,14 +6230,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6264,7 +6242,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6272,144 +6250,144 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 #, fuzzy msgid "The device is already unmounting." msgstr "Il dispositivo sta già smontando." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Il dispositivo è già montato." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Hostname non valido." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Partage" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6443,7 +6421,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6461,30 +6439,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6492,7 +6470,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6504,20 +6482,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6526,47 +6504,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6664,11 +6642,11 @@ msgstr "Servizio Onion" msgid "Ports" msgstr "Ports" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Aggiornamento della configurazione" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6726,14 +6704,14 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS can be accessed by any utente con un account su {box_name}." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6763,12 +6741,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6776,33 +6754,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Aggiornamento software" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox aggiornato" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6953,51 +6931,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7005,15 +6983,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -7031,21 +7009,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Password di autorizzazione" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Password non valida." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7054,12 +7032,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Fallito l'inserimento di un nuovo utente nel gruppo {group}: {error}" @@ -7075,41 +7053,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Aggiunta del nuovo utente al gruppo admin fallita: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Fallito la limitazione dell'accesso alla console: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -7126,12 +7104,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -7169,17 +7147,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -7210,34 +7188,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7546,7 +7524,7 @@ msgstr "Cancella Connessione a server" msgid "Server deleted." msgstr "Server cancellato." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7555,7 +7533,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7564,26 +7542,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Sito web e blog" @@ -7597,7 +7575,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7610,7 +7588,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7618,11 +7596,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7673,114 +7651,108 @@ msgstr "" msgid "Finished: {name}" msgstr "Servizio disabilitato: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Errore durante il backup" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Installa App" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Errore installazione applicazione: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Errore installazione applicazione: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Errore durante l'installazione dell'applicazione: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Errore durante l'installazione dell'applicazione: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Applicazione installata." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Ultimo aggiornamento" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Installa App" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Errore installazione applicazione: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Errore durante l'installazione dell'applicazione: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Applicazione installata." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7836,53 +7808,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -8147,6 +8120,30 @@ msgstr "" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Abilita DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Abilita Domain Name System Security Extensions" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Il demone del firewall non è in esecuzione. Abilitalo per favore. Il " +#~ "firewall è attivato di predefinito nel %(box_name)s. Sui qualsiasi " +#~ "sistema basato su Debian (come %(box_name)s) è possibile eseguirlo usando " +#~ "il comando 'service firewall start' o nol caso di un sistema con systemd " +#~ "'systemctl start firewalld'." + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Errore durante il backup" + #~ msgid "Network Connections" #~ msgstr "Connessione di rete" diff --git a/plinth/locale/ja/LC_MESSAGES/django.po b/plinth/locale/ja/LC_MESSAGES/django.po index a414473d5..fb5b524f2 100644 --- a/plinth/locale/ja/LC_MESSAGES/django.po +++ b/plinth/locale/ja/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-05-20 12:32+0000\n" "Last-Translator: Jacque Fresco \n" "Language-Team: Japanese calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1021,20 +1014,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1072,24 +1065,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1185,47 +1178,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1233,7 +1226,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1463,11 +1456,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1579,7 +1572,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1634,13 +1627,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1762,14 +1755,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1777,7 +1770,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1787,13 +1780,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1918,7 +1911,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1926,7 +1919,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1946,61 +1939,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2046,7 +2030,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2057,73 +2041,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2167,19 +2151,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2472,7 +2456,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2480,31 +2464,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2541,14 +2525,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2557,15 +2541,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2619,41 +2603,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2661,11 +2645,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2711,7 +2695,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2729,7 +2713,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2739,7 +2723,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2747,15 +2731,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2818,41 +2802,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2862,14 +2846,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2950,7 +2934,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2958,7 +2942,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2967,18 +2951,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3047,35 +3031,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3084,11 +3068,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3133,7 +3117,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3292,19 +3276,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3650,7 +3634,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3755,7 +3739,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3771,7 +3755,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3784,7 +3768,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4320,7 +4304,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4331,20 +4315,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4354,61 +4338,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4417,33 +4369,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4452,87 +4404,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4566,29 +4518,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4630,8 +4582,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4673,6 +4625,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4704,7 +4687,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4715,7 +4698,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4735,7 +4718,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4745,19 +4728,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4816,7 +4799,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4883,7 +4866,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4896,13 +4879,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4911,31 +4894,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5013,15 +4996,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5047,51 +5030,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5244,14 +5227,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5260,97 +5243,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5387,26 +5370,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5414,14 +5397,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5515,7 +5498,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5563,57 +5546,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5621,7 +5604,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5654,14 +5637,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5674,7 +5649,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5682,143 +5657,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5852,7 +5827,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5870,30 +5845,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5901,7 +5876,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5913,20 +5888,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5935,47 +5910,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6073,11 +6048,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6129,31 +6104,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6161,12 +6136,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6174,33 +6149,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6348,51 +6323,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6400,15 +6375,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6426,21 +6401,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6449,12 +6424,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6470,41 +6445,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6521,12 +6496,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6564,17 +6539,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6605,34 +6580,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6941,7 +6916,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6950,7 +6925,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6959,26 +6934,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6992,7 +6967,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7005,7 +6980,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7013,11 +6988,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7066,96 +7041,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7206,53 +7177,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "アプリ" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/kn/LC_MESSAGES/django.po b/plinth/locale/kn/LC_MESSAGES/django.po index e775b4750..11a48deb7 100644 --- a/plinth/locale/kn/LC_MESSAGES/django.po +++ b/plinth/locale/kn/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2020-07-16 16:41+0000\n" "Last-Translator: Yogesh \n" "Language-Team: Kannada calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1021,20 +1014,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1072,24 +1065,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1185,47 +1178,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1233,7 +1226,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1463,11 +1456,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1579,7 +1572,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1634,13 +1627,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1762,14 +1755,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1777,7 +1770,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1787,13 +1780,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1918,7 +1911,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1926,7 +1919,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1946,61 +1939,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2046,7 +2030,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2057,73 +2041,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2167,19 +2151,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2472,7 +2456,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2480,31 +2464,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2541,14 +2525,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2557,15 +2541,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2619,41 +2603,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2661,11 +2645,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2711,7 +2695,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2729,7 +2713,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2739,7 +2723,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2747,15 +2731,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2818,41 +2802,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2862,14 +2846,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2950,7 +2934,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2958,7 +2942,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2967,18 +2951,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3047,35 +3031,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3084,11 +3068,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3133,7 +3117,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3292,19 +3276,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3650,7 +3634,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3755,7 +3739,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3771,7 +3755,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3784,7 +3768,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4320,7 +4304,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4331,20 +4315,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4354,61 +4338,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4417,33 +4369,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4452,87 +4404,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4566,29 +4518,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4630,8 +4582,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4673,6 +4625,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4704,7 +4687,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4715,7 +4698,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4735,7 +4718,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4745,19 +4728,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4816,7 +4799,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4883,7 +4866,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4896,13 +4879,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4911,31 +4894,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5013,17 +4996,17 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "ಫ್ರೀಡಂಬಾಕ್ಸ್" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5049,51 +5032,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5246,14 +5229,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5262,97 +5245,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5389,26 +5372,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5416,14 +5399,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5517,7 +5500,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5565,57 +5548,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5623,7 +5606,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5656,14 +5639,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5676,7 +5651,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5684,143 +5659,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5854,7 +5829,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5872,30 +5847,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5903,7 +5878,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5915,20 +5890,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5937,47 +5912,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6075,11 +6050,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6131,31 +6106,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6163,12 +6138,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6176,33 +6151,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6350,51 +6325,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6402,15 +6377,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6428,21 +6403,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6451,12 +6426,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6472,41 +6447,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6523,12 +6498,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6566,17 +6541,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6607,34 +6582,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6943,7 +6918,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6952,7 +6927,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6961,26 +6936,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6994,7 +6969,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7007,7 +6982,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7015,11 +6990,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7068,96 +7043,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7208,53 +7179,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/lt/LC_MESSAGES/django.po b/plinth/locale/lt/LC_MESSAGES/django.po index 621b39731..866693cd2 100644 --- a/plinth/locale/lt/LC_MESSAGES/django.po +++ b/plinth/locale/lt/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Lithuanian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1023,20 +1016,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1074,24 +1067,24 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1187,47 +1180,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1235,7 +1228,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1465,11 +1458,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1581,7 +1574,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1636,13 +1629,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1764,14 +1757,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1779,7 +1772,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1789,13 +1782,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1920,7 +1913,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1928,7 +1921,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1948,61 +1941,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2048,7 +2032,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2059,73 +2043,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2169,19 +2153,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2474,7 +2458,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2482,31 +2466,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2543,14 +2527,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2559,15 +2543,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2621,41 +2605,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2663,11 +2647,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2713,7 +2697,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2731,7 +2715,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2741,7 +2725,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2749,15 +2733,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2820,41 +2804,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2864,14 +2848,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -2952,7 +2936,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2960,7 +2944,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2969,18 +2953,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3049,35 +3033,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3086,11 +3070,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3135,7 +3119,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3294,19 +3278,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3652,7 +3636,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3757,7 +3741,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3773,7 +3757,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3786,7 +3770,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4322,7 +4306,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4333,20 +4317,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4356,61 +4340,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4419,33 +4371,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4454,87 +4406,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4568,29 +4520,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4632,8 +4584,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4675,6 +4627,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4706,7 +4689,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4717,7 +4700,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4737,7 +4720,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4747,19 +4730,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4818,7 +4801,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4885,7 +4868,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4898,13 +4881,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4913,31 +4896,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5015,15 +4998,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5049,51 +5032,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5246,14 +5229,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5262,97 +5245,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5389,26 +5372,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5416,14 +5399,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5517,7 +5500,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5565,57 +5548,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5623,7 +5606,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5656,14 +5639,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5676,7 +5651,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5684,143 +5659,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5854,7 +5829,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5872,30 +5847,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5903,7 +5878,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5915,20 +5890,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5937,47 +5912,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6075,11 +6050,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6131,31 +6106,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6163,12 +6138,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6176,33 +6151,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6350,51 +6325,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6402,15 +6377,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6428,21 +6403,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6451,12 +6426,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6472,41 +6447,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6523,12 +6498,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6566,17 +6541,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6607,34 +6582,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6943,7 +6918,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6952,7 +6927,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6961,26 +6936,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6994,7 +6969,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7007,7 +6982,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7015,11 +6990,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7068,96 +7043,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7208,53 +7179,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/lv/LC_MESSAGES/django.po b/plinth/locale/lv/LC_MESSAGES/django.po index 2e7ba7572..fb96b5847 100644 --- a/plinth/locale/lv/LC_MESSAGES/django.po +++ b/plinth/locale/lv/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:20+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Latvian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1022,20 +1015,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1073,24 +1066,24 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1186,47 +1179,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1234,7 +1227,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1464,11 +1457,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1580,7 +1573,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1635,13 +1628,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1763,14 +1756,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1778,7 +1771,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1788,13 +1781,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1919,7 +1912,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1927,7 +1920,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1947,61 +1940,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2047,7 +2031,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2058,73 +2042,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2168,19 +2152,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2473,7 +2457,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2481,31 +2465,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2542,14 +2526,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2558,15 +2542,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2620,41 +2604,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2662,11 +2646,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2712,7 +2696,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2730,7 +2714,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2740,7 +2724,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2748,15 +2732,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2819,41 +2803,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2863,14 +2847,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -2951,7 +2935,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2959,7 +2943,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2968,18 +2952,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3048,35 +3032,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3085,11 +3069,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3134,7 +3118,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3293,19 +3277,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3651,7 +3635,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3756,7 +3740,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3772,7 +3756,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3785,7 +3769,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4321,7 +4305,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4332,20 +4316,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4355,61 +4339,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4418,33 +4370,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4453,87 +4405,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4567,29 +4519,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4631,8 +4583,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4674,6 +4626,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4705,7 +4688,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4716,7 +4699,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4736,7 +4719,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4746,19 +4729,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4817,7 +4800,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4884,7 +4867,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4897,13 +4880,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4912,31 +4895,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5014,15 +4997,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5048,51 +5031,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5245,14 +5228,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5261,97 +5244,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5388,26 +5371,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5415,14 +5398,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5516,7 +5499,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5564,57 +5547,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5622,7 +5605,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5655,14 +5638,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5675,7 +5650,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5683,143 +5658,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5853,7 +5828,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5871,30 +5846,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5902,7 +5877,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5914,20 +5889,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5936,47 +5911,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6074,11 +6049,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6130,31 +6105,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6162,12 +6137,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6175,33 +6150,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6349,51 +6324,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6401,15 +6376,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6427,21 +6402,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6450,12 +6425,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6471,41 +6446,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6522,12 +6497,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6565,17 +6540,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6606,34 +6581,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6942,7 +6917,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6951,7 +6926,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6960,26 +6935,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6993,7 +6968,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7006,7 +6981,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7014,11 +6989,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7067,96 +7042,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7207,53 +7178,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/nb/LC_MESSAGES/django.po b/plinth/locale/nb/LC_MESSAGES/django.po index b495a320c..8531ee367 100644 --- a/plinth/locale/nb/LC_MESSAGES/django.po +++ b/plinth/locale/nb/LC_MESSAGES/django.po @@ -15,9 +15,9 @@ msgid "" msgstr "" "Project-Id-Version: FreedomBox UI\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" -"PO-Revision-Date: 2022-09-14 17:19+0000\n" -"Last-Translator: ikmaak \n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" +"PO-Revision-Date: 2022-10-09 07:43+0000\n" +"Last-Translator: Petter Reinholdtsen \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" @@ -25,7 +25,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: doc/dev/_templates/layout.html:11 msgid "Page source" @@ -62,11 +62,11 @@ msgstr "Klarer ikke koble til {host}:{port}" #: plinth/forms.py:36 msgid "Backup app before uninstall" -msgstr "" +msgstr "Sikkerhetskopier program før avinstallasjon" #: plinth/forms.py:37 msgid "Restoring from the backup will restore app data." -msgstr "" +msgstr "Tilbakeføring av sikkerhetskopi vil tilbakestille programdata." #: plinth/forms.py:39 #, fuzzy @@ -124,17 +124,17 @@ msgstr "Nett-tjener" msgid "{box_name} Web Interface (Plinth)" msgstr "{box_name} Vev-grensesnitt (Plinth)" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "Kontakt nettadressen {url} på tcp{kind}" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "Kontakt nettadressen {url}" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -151,25 +151,25 @@ msgstr "" "kan slås av for å bedre sikkerheten, spesielt ved tilkobling til et " "fiendtlig/fremmed lokalt nettverk." -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "Tjenesteoppdagelse" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "Lokalt nettverksdomene" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "" "Sikkerhetskopier tillater opprettelse og behandling av sikkerhetskopiarkiver." -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "Sikkerhetskopier" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." @@ -178,18 +178,18 @@ msgstr "" "Bruke helst et kryptert fjernlager eller en ekstern ekstradisk som " "sikkerhetslager." -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "Aktiver sikkerhetskopitidsplan" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "Gå til {app_name}" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " @@ -198,7 +198,7 @@ msgstr "" "En sikkerhetskopi på tidsplanen feilet. De {error_count} foregående " "forsøkene lyktes heller ikke. Den siste feilen er: {error_message}" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "Feil under sikkerhetskopiering" @@ -334,7 +334,7 @@ msgstr "" msgid "Key in Repository" msgstr "Nøkkel i kodelager" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "Ingen" @@ -402,7 +402,7 @@ msgstr "Kodelager annensteds hen for sikkerhetskopi finnes allerede." msgid "Select verified SSH public key" msgstr "Velg bekreftet offentlig SSH-nøkkel" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." @@ -410,33 +410,33 @@ msgstr "" "Oppkobling avvist - sikre at du oppga korrekte innloggingsinformasjon og at " "tjenermaskinen kjører." -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "Oppkobling avvist" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "Finner ikke kodelager" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "Feil krypteringspassfrase" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "Nektes SSH-tilgang" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" "Pakkebrønnssti er hverken tom eller en eksisterende " "sikkerhetskopieringspakkebrønn." -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "Eksisterende pakkebrønn er ikke kryptert." -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "{box_name} lager" @@ -498,7 +498,7 @@ msgid "Create Location" msgstr "Opprett plassering" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "Opprett kodelager" @@ -747,7 +747,7 @@ msgstr "Klarte ikke å avmontere!" msgid "Mounting failed" msgstr "Montering feilet" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -759,7 +759,7 @@ msgstr "" "og PDF-dokumenter kan forhåndsvises i nettleseren. Delte filer kan stilles " "inn til å forsvinne etter en gitt tidsperiode." -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -771,7 +771,7 @@ msgstr "" "passord så kan du dele det med brukerne som skal ha de tilhørende " "rettighetene." -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -783,39 +783,39 @@ msgstr "" "senere for en enkelt person eller gruppe, ved å fjerne passordet deres fra " "listen." -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "Les en fil, vis en nettadresse til filen er tilgjengelig" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "Opprett eller last opp filer" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "List opp alle filer og deres nettadresser" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "Slett filer" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "Administrer filer: Lås/lås opp filer" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "Ingen, passord kreves alltid" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "List opp og les alle filer" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "bepasty" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "Deling av filer og snutter" @@ -829,7 +829,7 @@ msgstr "Tilganger for anonyme brukere, som ikke har angitt et passord." #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "Tilganger" @@ -865,37 +865,37 @@ msgstr "Ingen passord er foreløpig satt opp." #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "Passord" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "admin" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 #, fuzzy #| msgid "Repository" msgid "editor" msgstr "Kodelager" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "fremviser" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "Les" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "Opprett" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "List opp" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -907,35 +907,35 @@ msgstr "List opp" msgid "Delete" msgstr "Slett" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "admin" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "Konfigurering oppdatert." -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "En feil oppsto under konfigureringen." -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "Passord lagt til." -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "Legg til passord" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "Passord slettet." -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." @@ -944,7 +944,7 @@ msgstr "" "Internett, og å slå opp dine DNS-forespørsler for dine brukeres enheter på " "ditt nettverk." -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -955,33 +955,25 @@ msgstr "" "maskiner på lokalnettverket. Det er også inkompatibelt med deling av " "internettilknytning fra {box_name}." -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "BIND" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "Domenenavnetjener" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "Videresendere" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" "En mellomromsinndelt liste over DNS-tjenere, som forespørsler vil bli " "videresendt til" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "Aktiver DNSSEC" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "Aktiver domenenavnsystemets sikkerhetsutvidelser" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "Betjener domener" @@ -1013,19 +1005,20 @@ msgstr "IP-adresser" msgid "Refresh IP address and domains" msgstr "Oppdater IP-adresse og domener" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "Oppsett oppdatert" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -1035,7 +1028,7 @@ msgstr "" "calibre-tjener tilbyr nettbasert tilgang til din e-boksamling. Du kan lagre " "e-bøker på din {box_name}, lese dem på nett, eller fra en av enhetene dine." -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -1050,7 +1043,7 @@ msgstr "" "bokmerker og framhevet tekst. Innholdsdistribusjon ved bruk av OPDS støttes " "ikke foreløpig." -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1058,29 +1051,29 @@ msgstr "" "Kun brukere som tilhører calibre-gruppen vil ha tilgang til " "programmet. Alle brukere med tilgang kan bruke alle bibliotekene." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Bruk calibre ebokbibliotek" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-bok-bibliotek" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Navn på nytt bibliotek" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Det finnes allerede et bibliotek med dette navnet." @@ -1128,22 +1121,22 @@ msgstr "Gå til biblioteket %(library)s" msgid "Delete library %(library)s" msgstr "Slett biblioteket %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Bibliotek opprettet." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 #, fuzzy #| msgid "An error occurred during configuration." msgid "An error occurred while creating the library." msgstr "En feil oppsto under konfigureringen." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "Slettet {name}." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Kunne ikke slette {name}: {error}" @@ -1191,7 +1184,7 @@ msgstr "Styrhus" msgid "Server Administration" msgstr "Tjeneradministrasjon" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1199,18 +1192,18 @@ msgstr "" "Her kan du sette noen generelle oppsettsvalg som vertsnavn, domenenavn, " "vevtjener-hjemmeside, etc." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Generelt oppsett" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Oppsett" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1323,47 +1316,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Feil ved setting av vertsnavn: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Vertsnavn satt" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Feil ved innstilling/setting av domenenavn: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Domenenavn satt" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Feil ved setting av nettstedets hjemmeside: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Webtjenerforside satt" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Feil ved bytte til avansert modus: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Viser avanserte programmer og funksjoner" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Viser ikke avanserte programmer og funksjoner" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1375,7 +1368,7 @@ msgstr "" "kommunikasjonstjenere kan bruke det for å etablere en samtale mellom parter " "som ellers ikke ville kunne kontakte hverandre." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse eller ejabberd må " "settes opp med detaljene herfra." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP-hjelper" @@ -1449,11 +1442,11 @@ msgstr "Feil ved setting av tidssone: {exception}" msgid "Time zone set" msgstr "Tidssone satt" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge er en BitTorrent-klient som har et Web-grensesnitt." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1461,16 +1454,16 @@ msgstr "" "Standardpassordet er «deluge», men du bør logge inn og endre det umiddelbart " "etter at denne tjenesten er aktivert." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Last ned filer ved bruk av BitTorrent-programmer" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent nett-klient" @@ -1600,7 +1593,7 @@ msgstr "Resultat" msgid "Diagnostic Test" msgstr "Diagnostikktest" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1611,7 +1604,7 @@ msgstr "" "eks. hver 24 t), kan det være vanskelig for andre å finne deg på Internett. " "Dette vil hindre andre i å finne tjenester som tilbys av dette {box_name}et." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1628,7 +1621,7 @@ msgstr "" "tjeneren tildele DNS-navnet ditt til den nye IP-en. Hvis noen fra Internett " "ber om ditt DNS-navn, vil de da få svar med din gjeldende IP-adresse." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 #, fuzzy #| msgid "" #| "If you are looking for a free dynamic DNS account, you may find a free " @@ -1648,11 +1641,11 @@ msgstr "" "baserte oppdateringstjenester her freedns.afraid.org ." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Dynamisk DNS-klient" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dynamisk domenenavn" @@ -1788,7 +1781,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1857,7 +1850,7 @@ msgstr "Slett tilkobling" msgid "Already up-to-date" msgstr "Auto-oppdatering" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1865,7 +1858,7 @@ msgstr "" "XMPP er en åpen og standardisert kommunikasjonsprotokoll. Her kan du kjøre " "og konfigurere din XMPP-tjener, kalt ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientbruker med innlogging på " "{box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Nettprat-tjener" @@ -2009,22 +2002,30 @@ msgstr "" "se slik ut: username@%(domainname)s. Du kan sette opp ditt domene på " "systemsiden Configure ." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" +"Dette er en komplett eposttjenerløsning som bruker Postfix, Dovecot og " +"Rspamd. Postfix sender og mottar e-post. Dovecot gir e-postklienter tilgang " +"til din postkasse ved hjelp av IMAP og POP3. Rspamd håndterer spam." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " "restrict outgoing email. Some lift the restriction after an explicit " "request. See manual page for more information." msgstr "" +"Eposttjeneren virker for øyeblikket ikke med mange gratis domenetjenester, " +"inkludert de som tilbys fra Freedombox-stiftelsen. Mange " +"internettleverandører begrenser også utgående epost. Noen løfter på " +"blokkeringen etter eksplisitte henvendelser. Se manualsiden for mer " +"informasjon." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2034,27 +2035,25 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." -msgstr "" +msgstr "Enhver annen eposttjener vil bli avinstallert under installasjonen." #: plinth/modules/email/__init__.py:61 msgid "Postfix/Dovecot" msgstr "Postfix/Dovecot" #: plinth/modules/email/__init__.py:63 -#, fuzzy -#| msgid "Chat Server" msgid "Email Server" -msgstr "Nettprat-tjener" +msgstr "Eposttjener" #: plinth/modules/email/__init__.py:83 #, fuzzy @@ -2183,7 +2182,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2194,7 +2193,7 @@ msgstr "" "utgående nettverkstrafikk på din {box_name}. Å holde en brannmur aktivert og " "riktig konfigurert, reduserer risikoen for sikkerhetstrusler fra Internett." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Brannmur" @@ -2214,52 +2213,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} ({details}) er utilgjengelig for eksterne nettverk" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Brannmur-bakgrunnsprosessen kjører ikke. Den må kjøre. Brannmuren kommer som " -"standard aktivert på %(box_name)s. På et Debian-basert system (slik som " -"%(box_name)s), kan du kjøre den med kommandoen «service firewalld start», " -"eller alternativt i et system med systemd, «systemctl start firewalld»." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Tjeneste/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Aktivert" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Deaktivert" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Tillatt" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Tillatt (kun internt)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Tillatt (kun eksternt)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Blokkert" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2269,13 +2255,13 @@ msgstr "" "også tillatt i brannmuren, og når du deaktiverer en tjeneste, er den også " "deaktivert i brannmuren." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Avansert" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2328,7 +2314,7 @@ msgstr "Gå i gang med oppsett" msgid "Setup Complete" msgstr "Oppsett ferdig" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2346,7 +2332,7 @@ msgstr "" "flerfoldige grafiske klienter. Du kan også dele koden med folk rundt omkring " "i verden." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2354,28 +2340,27 @@ msgstr "" "For å lære mer om bruk av Git, besøk Git-veiledningen." -#: plinth/modules/gitweb/__init__.py:49 -#, fuzzy +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Lese- og skrivetilgang til Git-kodelagre" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Enkelt Git-vertsskap" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Ugyldig kodelager-nettadresse." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Ugyldig kodelagernavn." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 #, fuzzy #| msgid "" #| "Repository path is neither empty nor is an existing backups repository." @@ -2384,39 +2369,38 @@ msgstr "" "Pakkebrønnssti er hverken tom eller en eksisterende " "sikkerhetskopieringspakkebrønn." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Beskrivelse av kodelageret" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 #, fuzzy msgid "Optional, for displaying on Gitweb." msgstr "Valgfritt, for visning på Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Kodelagereierens navn" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Privat kodelager" -#: plinth/modules/gitweb/forms.py:92 -#, fuzzy +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." -msgstr "Tillat kun autoriserte brukere tilgang til dette kodelageret." +msgstr "Gi kun autoriserte brukere tilgang til dette kodelageret." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 #, fuzzy #| msgid "A share with this name already exists." msgid "A repository with this name already exists." msgstr "En deling ved dette navnet finnes allerede." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Navn på kodelager" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 #, fuzzy #| msgid "" #| "A lowercase alpha-numeric string that uniquely identifies a share. " @@ -2424,13 +2408,13 @@ msgstr "Navn på kodelager" msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "En alfanumerisk streng som unikt identifiserer et kodelager." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Default Skin" msgid "Default branch" msgstr "Forvalgt drakt" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb biser dette som forvalgt forgrening." @@ -2475,21 +2459,21 @@ msgstr "Slett Git-kodelager %(name)s" msgid "Delete this repository permanently?" msgstr "Slett dette kodelageret for godt?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Kodelager opprettet." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 #, fuzzy #| msgid "An error occurred during configuration." msgid "An error occurred while creating the repository." msgstr "En feil oppsto under konfigureringen." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Kodelager redigert.." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Rediger kodelager" @@ -2856,7 +2840,7 @@ msgstr "Om {box_name}" msgid "{box_name} Manual" msgstr "{box_name} Manual" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2868,7 +2852,7 @@ msgstr "" "anonymitet ved å sende kryptert trafikk gjennom et frivilligdrevet nettverk " "distribuert verden om." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2876,7 +2860,7 @@ msgstr "" "For mer informasjon om I2P, sjekk deres nettside." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2884,19 +2868,19 @@ msgstr "" "Den første til å besøke det oppsatte nettgrensesnittet vil igangsette " "oppsettsprosessen." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Håndter I2P-program" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Anonymitetsnettverk" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P-mellomtjener" @@ -2914,11 +2898,6 @@ msgid "Anonymous Torrents" msgstr "Anonyme torrenter" #: plinth/modules/i2p/views.py:16 -#, fuzzy -#| msgid "" -#| "I2P lets you browse the Internet and hidden services (eepsites) " -#| "anonymously. For this, your browser, preferably a Tor Browser, needs to " -#| "be configured for a proxy." msgid "" "I2P lets you browse the Internet and hidden services (eepsites) anonymously. " "For this, your browser, preferably the Tor Browser, needs to be configured " @@ -2947,7 +2926,7 @@ msgstr "" "likemannsnettverk. Last ned filer ved å legge til torrenter, eller opprett " "en ny torrent for å dele ei fil." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2957,7 +2936,7 @@ msgstr "" "lettvektsoppmerkingsspråk, inkludert Markdown, og vanlige bloggfunksjoner " "som kommentarer og RSS-informasjonskilder." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2971,15 +2950,15 @@ msgstr "" "\"{users_url}\">brukeroppsettet kan du endre disse tilgangene eller " "legge til nye brukere." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki og Blogg" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Vis og rediger wiki-programmer" @@ -3035,41 +3014,41 @@ msgstr "" "Denne handlingen vil fjerne alle poster, sider og kommentarer inkludert " "revisjonshistorien. Skal denne wiki-en eller bloggen slettes for godt?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Opprettet wiki {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Kunne ikke opprette wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Opprettet blogg {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Kunne ikke lage blogg: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} slettet." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Kunne ikke slette {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted er en tjener for Gobby, en samskrivende teksteditor." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3080,11 +3059,11 @@ msgstr "" "skrivebordsklient og installer den. Deretter starter du Gobby og velger " "«Koble til tjener», og skriver inn domenenavnet til din {box_name} ." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby-tjener" @@ -3111,7 +3090,7 @@ msgstr "" #: plinth/modules/janus/__init__.py:23 msgid "A simple video conference room is included." -msgstr "" +msgstr "Et enkelt videokonferanserom er med." #: plinth/modules/janus/__init__.py:25 #, python-brace-format @@ -3124,15 +3103,15 @@ msgstr "Janus" #: plinth/modules/janus/__init__.py:43 msgid "Video Room" -msgstr "" +msgstr "Videorom" #: plinth/modules/janus/manifest.py:7 msgid "Janus Video Room" -msgstr "" +msgstr "Janus videorom" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "JavaScript lisensinformasjon" @@ -3152,7 +3131,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Nettpratklient" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3167,7 +3146,7 @@ msgstr "" "ved at det selv bekrefter eierskapet til et domene overfor " "sertifiseringsinstansen (CA) Let's Encrypt." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3179,15 +3158,15 @@ msgstr "" "les og aksepter Let's " "Encrypt Subscriber Agreement før tjenesten brukes." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Sertifikater" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3252,7 +3231,7 @@ msgstr "" "Ingen domener er satt opp. Sett opp domener " "for å kunne skaffe sertifikater for dem." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3261,34 +3240,34 @@ msgstr "" "Sertifikat tilbakekalt for domenet {domain}. Det kan ta en liten stund før " "dette tar effekt." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Klarte ikke å inndra sertifikatet for domenet {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Sertifikat vellykket innhentet til domene {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Klarte ikke å oppnå sertifikat til domene {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Vellykket sletting av sertifikatet for domenet {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Klarte ikke å slette sertifikatet for domenet {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3304,14 +3283,14 @@ msgstr "" "enheter, og krever ikke telefonnumre for å virke. Brukere på en gitt Matrix-" "tjener kan snakke med brukere på alle andre samvirkende Matrix-tjenere." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3413,7 +3392,7 @@ msgstr "" "Matrix Synapse-instanser krever et gyldig TLS-sertifikat. Gå til Let's Encrypt for å skaffe deg det." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3426,7 +3405,7 @@ msgstr "" "lignende nettside, ta noteter, eller samarbeide med andre venner på " "prosjekter." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3440,7 +3419,7 @@ msgstr "" "brukerkontoer fra MediaWiki, ved å gå til Special:CreateAccount-siden." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3448,12 +3427,12 @@ msgstr "" "Alle med en lenke til denne wiki-en kan lese den. Kun innloggede brukere kan " "endre innholdet." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3536,39 +3515,35 @@ msgstr "Passord oppdatert" msgid "Password update failed. Please choose a stronger password" msgstr "Passordoppdatering feilet. Vennligst bruk ett sterkere passord" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Offentlig registrering aktivert" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Offentlig registrering avskrudd" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Privat modus påskrudd" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Privat modus avskrudd" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Forvalgt drakt endret" -#: plinth/modules/mediawiki/views.py:102 -#, fuzzy -#| msgid "Domain name set" +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" -msgstr "Domenenavn satt" +msgstr "Domenenavn oppdatert" -#: plinth/modules/mediawiki/views.py:106 -#, fuzzy -#| msgid "Domain name set" +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" -msgstr "Domenenavn satt" +msgstr "Stedsnavn oppdatert" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, fuzzy, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3581,11 +3556,11 @@ msgstr "" "porten (30000). For å koble til tjeneren trengs en Minetest-klient." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Block-sandkassen" @@ -3635,7 +3610,7 @@ msgstr "" msgid "Address" msgstr "Adresse" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3787,10 +3762,8 @@ msgid "Mumla" msgstr "Mumla" #: plinth/modules/mumble/views.py:43 -#, fuzzy -#| msgid "Password changed successfully." msgid "SuperUser password successfully updated." -msgstr "Vellykket passordbytte." +msgstr "Vellykket passordbytte for SuperUser." #: plinth/modules/mumble/views.py:48 #, fuzzy @@ -3843,7 +3816,7 @@ msgstr "Secure Shell (SSH)" msgid "Services" msgstr "Tjeneste" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3851,7 +3824,7 @@ msgstr "" "Sett opp nettverksenheter. Sett opp Internett via Ethernet, Wi-Fi eller " "PPPoE. Del den tilkoblingen med andre enheter på nettverket." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3859,7 +3832,7 @@ msgstr "" "Enheter administrert gjennom andre metoder kan være utilgjengelige for " "oppsett her." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Nettverk" @@ -4242,7 +4215,7 @@ msgstr "Rediger tilkobling" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Rediger" @@ -4347,7 +4320,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Metode" @@ -4363,7 +4336,7 @@ msgstr "DNS-tjener" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Forvalg" @@ -4376,7 +4349,7 @@ msgid "This connection is not active." msgstr "Denne forbindelsen er ikke aktiv." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Sikkerhet" @@ -4985,7 +4958,7 @@ msgstr "Tilkobling {name} slettet." msgid "Failed to delete connection: Connection not found." msgstr "Kunne ikke slette tilkobling: Tilkobling ikke funnet." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -5002,22 +4975,22 @@ msgstr "" "Du kan også få tilgang til resten av Internettet via {box_name} med utvidet " "sikkerhet og anonymitet." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection Type" msgid "Connect to VPN services" msgstr "Oppkoblingstype" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Virtuelt privat nettverk" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5028,50 +5001,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -#, fuzzy -#| msgid "Moderate" -msgid "Migrate" -msgstr "Moderat" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "For å koble til %(box_name)s VPN må du laste ned en profil og legge den til " @@ -5079,18 +5023,19 @@ msgstr "" "er tilgjengelig for de fleste plattformer. Klikk «Lær mer …» ovenfor, for " "anbefalte klienter, og instruksjoner om hvordan de settes opp." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Profilen er spesifikk for hver enkelt bruker av %(box_name)s. Hold den " "hemmelig." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Last ned min profil" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5103,17 +5048,17 @@ msgstr "" "{box_name}-tjenester ikke nås fra resten av nettet. Dette omfatter de " "følgende situasjoner:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} er bak en begrensende brannmur." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "{box_name} er koblet til en (trådløs) ruter du ikke kan kontrollere." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5121,7 +5066,7 @@ msgstr "" "Din Internett-leverandør gir deg ikke en ekstern IP-adresse, og gir i stedet " "en NAT-et Internett-tilkobling." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5129,11 +5074,11 @@ msgstr "" "Internett-leverandøren gir deg ikke en statisk IP-adresse, og IP-adressen " "endres hver gang du kobler deg til Internett." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Din Internett-leverandør begrenser innkommende oppkoblinger." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, fuzzy, python-brace-format #| msgid "" #| "PageKite works around NAT, firewalls and IP-address limitations by using " @@ -5153,23 +5098,23 @@ msgstr "" "\"https://pagekite.net\">pagekite.net. I fremtiden kan det bli mulig å " "bruke kameratens {box_name} til dette." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Offentlig synlighet" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite-domene" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Tjenerdomene" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5177,31 +5122,31 @@ msgstr "" "Velg din PageKite-tjener. Sett «pagekite.net» for å bruke den forvalgte " "pagekite.net-tjeneren." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Tjenerport" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Port for din PageKite-tjener (default: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "«Kite»-navn" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Eksempel: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Ugyldig «kite»-navn" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "«Kite»-hemmelig" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5209,27 +5154,27 @@ msgstr "" "En hemmelighet knyttet til «Kite»-en, eller den forvalgte hemmeligheten for " "din konto hvis ingen hemmelighet er satt for «Kite»-en." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokoll" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "Ekstern (frontend) port" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "intern (FreedomBox) port" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Tillat underdomener (Subdomains)" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Deaktivert selvvalgt (tilpasset) tjeneste" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 #, fuzzy #| msgid "" #| "This service is available as a standard service. Please use the " @@ -5239,11 +5184,11 @@ msgstr "" "Denne tjenesten er tilgjengelig som en standard tjeneste. Vennligst bruk " "«Standard Services»-siden for å aktivere den." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Lagt til selvvalgt tjeneste" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Denne tjenesten finnes allerede" @@ -5284,31 +5229,31 @@ msgstr "" "alle protokoll-/portkombinasjoner som du kan definere her. For eksempel, " "HTTPS på andre ting enn 443 er kjent for å forårsake problemer." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Web-tjener (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" "Nettstedet vil være tilgjengelig på http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Web-tjener (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" "Nettstedet vil bli tilgjengelig på https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5335,10 +5280,8 @@ msgid "" msgstr "" #: plinth/modules/performance/__init__.py:41 -#, fuzzy -#| msgid "System Configuration" msgid "System Monitoring" -msgstr "Systemoppsett" +msgstr "Systemmonitorering" #: plinth/modules/power/__init__.py:14 msgid "Restart or shut down the system." @@ -5356,8 +5299,8 @@ msgstr "" "En annen installasjon eller oppgradering kjører allerede. Vent litt før du " "prøver igjen." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Omstart" @@ -5409,6 +5352,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Slå av nå" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5455,7 +5431,7 @@ msgstr "Mellomtjener for nettet" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Tilgang {url} med mellomtjener {proxy} på tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5472,7 +5448,7 @@ msgstr "" "skrivebordet kan en eller flere Quassel-klienter brukes til å koble til og " "fra." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your desktop , og mobile enheter er tilgjengelig." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC-klient" @@ -5496,7 +5472,7 @@ msgstr "IRC-klient" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5515,7 +5491,7 @@ msgstr "" "href=\"http://radicale.org/clients/\">støttet klientprogram . Radicale " "kan nås av alle brukere med {box_name}-innlogging." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5525,12 +5501,12 @@ msgstr "" "kalendre og adressebøker. Den tilbyr ikke å legge inn nye hendelser eller " "kontakter, det må gjøres med en egen klient." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Kalender og adressebok" @@ -5606,7 +5582,7 @@ msgstr "" "freedombox.adresse>) og ditt brukernavn. Å klikke på søkeknappen vil " "liste opp eksisterende kalendre og adressebøker." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Tilgangskontrolloppsett oppdatert" @@ -5673,16 +5649,13 @@ msgid "" msgstr "" #: plinth/modules/rssbridge/__init__.py:23 -#, fuzzy, python-brace-format -#| msgid "" -#| "When enabled, Tiny Tiny RSS can be accessed by any user with a {box_name} login." +#, python-brace-format msgid "" "When enabled, RSS-Bridge can be accessed by any " "user belonging to the feed-reader group." msgstr "" -"Tiny Tiny RSS er tilgjengelig for enhver bruker med " -"et {box_name}-brukernavn." +"Når RSS-Bridge er aktiv er den tilgjengelig for enhver bruker som er medlem av gruppen feed-reader." #: plinth/modules/rssbridge/__init__.py:27 #, python-brace-format @@ -5692,7 +5665,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Les og abonner på nyhetsstrømmer" @@ -5707,13 +5680,13 @@ msgstr "Bro" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5722,31 +5695,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Tilgang til private delinger" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Distributed File Storage" msgid "Network File Storage" @@ -5835,15 +5808,15 @@ msgstr "Delingsnavn" msgid "Action" msgstr "Handlinge" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS disk" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Åpne deling" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 #, fuzzy #| msgid "Add Share" msgid "Group Share" @@ -5877,7 +5850,7 @@ msgstr "Deling redigert." msgid "Error disabling share: {error_message}" msgstr "Feil ved utløsing av enhet: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5885,7 +5858,7 @@ msgstr "" "Searx er en metasøkemotor for Internett som tar hensyn til personvernet. Den " "henter og viser resultater fra flere søkemotorer." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5893,41 +5866,41 @@ msgstr "" "Searx kan brukes for å unngå sporing og profilbygging av søkemotorer. Den " "lagrer ingen kaker som forvalg." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Søk på nettet" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Nettsøk" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Trygt søk" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Velg hvilket forvalgt familiefilter som skal anvendes for dine " "søkeresultater." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Moderat" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Streng" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Tillat offentlig tilgang" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "Tillat dette programmet brukt av alle som kan nå det." @@ -6112,7 +6085,7 @@ msgstr "Bokmerker" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6122,7 +6095,7 @@ msgstr "" "beskytte din internettrafikk. Den kan brukes til å omgå internettfiltrering " "og -sensur." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6130,12 +6103,12 @@ msgid "" "connect to this proxy, and their data will be encrypted and proxied through " "the Shadowsocks server." msgstr "" -"Din {box_name} kan kjøre en Shadowsocks-klient, som kan koble til en " +"Din {box_name} kan kjøre en Shadowsocks-klient, som kan koble set til en " "Shadowsocks-tjener. Den vil også kjøre en SOCKS5-mellomtjener. Lokale " "enheter kan koble til denne mellomtjeneren, og deres data vil krypteres og " -"mellomtjent gjennom Shadowsocks-tjeneren." +"sendes via Shadowsocks-tjeneren." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6143,40 +6116,40 @@ msgstr "" "For å bruke Shadowsocks etter oppsett, legg SOCKS5-mellomtjenernettadresen " "på din enhet, nettleser, eller program til http://freedombox_address:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "SOCKS5-mellomtjener" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Anbefalt" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Tjener" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Tjernens vertsnavn eller IP-adresse" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Tjener-portnummer" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "Passord brukt for å kryptere data. Må samsvare med tjenerpassord." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Krypteringsmetode. Må samsvare med den brukt på tjeneren." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6185,15 +6158,15 @@ msgstr "" "Deling lar deg dele filer og mapper på din {box_name} over nettet, med en " "utvalgt gruppe brukere." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Deling" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Navn på delt område" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6201,27 +6174,27 @@ msgstr "" "En alfanumerisk streng med små bokstaver som unikt identifiserer en deling. " "Eksempel media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Sti å dele" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Disksti til en mappe på denne tjeneren som du ønsker å dele." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Del offentlig" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Gjør filene i denne mappen tilgjengelig for alle som har lenken." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Brukergrupper som kan lese filene på det delte området:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6229,11 +6202,11 @@ msgstr "" "Brukere i de utvalgte brukergruppene vil også kunne lese filene i det delte " "området." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "En deling ved dette navnet finnes allerede." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Delte områder bør enten være offentlig eller delt med minst en gruppe" @@ -6270,19 +6243,19 @@ msgstr "Deling lagt til." msgid "Add Share" msgstr "Legg til deling" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Deling redigert." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Rediger deling" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Deling slettet." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6293,7 +6266,7 @@ msgstr "" "tidligere kjent god tilstand i tilfelle det har skjedd uønskede endringer på " "systemet." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6304,7 +6277,7 @@ msgstr "" "etter programvareinstallasjon. Eldre øyeblikksbilder renskes automatisk i " "henhold til innstillingene nedenfor." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for sikkerhetskopier i og med at de er lagret på samme partisjon. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Lagrings-avbildninger" @@ -6421,7 +6394,7 @@ msgstr "Dato" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Slett avbildninger" @@ -6480,57 +6453,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Rull tilbake til øyeblikksbilde #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "manuelt opprettet" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "tidslinje" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Behandle avbildninger" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Opprett øyeblikksbilde." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Oppsett for lagringsavbildninger oppdatert" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Handlingsfeil: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Slettet alle valgte avbildninger" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Øyeblikksbilde i bruk. Prøv igjen senere." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Rullet tilbake til øyeblikksbilde #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Systemet må startes på nytt for å fullføre tilbakerullingen." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Rull tilbake til øyeblikksbilde" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6542,7 +6515,7 @@ msgstr "" "annensteds hen kan utføre administrasjonsoppgaver, kopiere filer eller kjøre " "andre tjenester ved bruk av slike tilkoblinger." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Secure Shell (SSH) tjener" @@ -6585,14 +6558,6 @@ msgstr "Algoritme" msgid "Fingerprint" msgstr "SSH Fingeravtrykk" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "SSH-identitetsbekreftelse med passord avskrudd." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "SSH-autentisering med passord aktivert." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Engangspålogging" @@ -6607,7 +6572,7 @@ msgstr "Login" msgid "Logged out successfully." msgstr "Vellykket passordbytte." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6618,92 +6583,92 @@ msgstr "" "kan vise lagringsmedia som er i bruk, montere og avmontere flyttbare medium, " "utvide rotpartisjonen, osv." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Lager" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} byte" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Operasjonen mislyktes." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Operasjonen ble avbrutt." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Enheten avmonteres allerede." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "Denne aktiviteten støttes ikke på grunn av manglende driver-/verktøystøtte." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Tidsavbrudd for operasjon." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "Operasjonen vil vekke en disk fra en tilstand av dyp søvn." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Prøver å avmontere en opptatt enhet." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Operasjonen har allerede blitt avbrutt." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Mangler rettigheter til utførelse av forespurt operasjon." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Denne enheten er allerede montert." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Enheten er ikke montert." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Mangler rettigheter til bruk av forespurt valg." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Enheten er montert av en annen bruker." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, fuzzy, no-python-format, python-brace-format #| msgid "" #| "Warning: Low space on system partition ({percent_used}% used, " @@ -6713,15 +6678,15 @@ msgstr "" "Advarsel: Lite plass igjen på systempartisjon ({percent_used}% brukt, " "{free_space} ledig)." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Lite ledig diskplass" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Diskfeil nært forestående" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6730,39 +6695,39 @@ msgstr "" "Disk {id} rapporterer at den sannsynligvis vil feile i nær fremtid. Kopier " "all data mens det fremdeles er mulig og bytt ut disken." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Ugyldig katalognavn." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Mappen finnes ikke." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Stien er ikke en katalog." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Katalogen er ikke leselig for brukeren." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Mappen kan ikke skrives til av brukeren." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Katalog" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Undermappe (valgfritt)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Del" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Annen mappe (angi nedenfor)" @@ -6799,7 +6764,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Utvid root-partisjon" @@ -6820,30 +6785,30 @@ msgstr "" "operasjonen vil det være %(expandable_root_size)s med ekstra plass " "tilgjengelig på root-partisjonen din." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Utviding av partisjon feilet: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Vellykket partisjonsutvidelse." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} kan trygt kobles fra." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Enheten kan trygt kobles fra." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Feil ved utløsing av enhet: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6854,7 +6819,7 @@ msgstr "" "Oppretting, endring og sletting av filer på én enhet vil automatisk bli " "replikert (gjenskapt) til andre enheter." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, fuzzy, python-brace-format #| msgid "" #| "Running Syncthing on {box_name} provides an extra synchronization point " @@ -6879,20 +6844,20 @@ msgstr "" "med sine egne sett med mapper. Webgrensesnittet er bare tilgjengelig for " "brukere som hører til i «admin»-gruppen." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Administrer Syncthing-programmet" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Filsynkronisering" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6906,49 +6871,49 @@ msgstr "" "\"https://www.torproject.org/download/download-easy.html.en\">Tor Browser." -#: plinth/modules/tor/__init__.py:34 -#, fuzzy, python-brace-format -#| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." +#: plinth/modules/tor/__init__.py:30 +#, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -"En Tor SOCKS-port er tilgjengelig på din %(box_name)s på TCP port 9050." +"En Tor SOCKS-port er tilgjengelig på din {box_name} for interne nettverk på " +"TCP port 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor-løktjeneste" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor Socks-mellomtjener" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor bro-stafettvideresendingsoppsett" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor relay-port tilgjengelig" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3-transport registrert" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4-transport registrert" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Adgang til URL {url} på tcp{kind} via Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Bekreft Tor-bruk på {url} via tcp{kind}" @@ -7018,10 +6983,8 @@ msgstr "" "vanskeligere å sensurere denne noden. Dette hjelper andre å unngå sensur." #: plinth/modules/tor/forms.py:104 -#, fuzzy -#| msgid "Enable Tor Hidden Service" msgid "Enable Tor Hidden Service" -msgstr "Aktiver skjulte Tor-tjenester" +msgstr "Aktiver skjult Tor-tjeneste" #: plinth/modules/tor/forms.py:106 #, python-brace-format @@ -7030,9 +6993,9 @@ msgid "" "wiki or chat) without revealing its location. Do not use this for strong " "anonymity yet." msgstr "" -"En skjult tjeneste som vil tillate {box_name} å gi valgte tjenester (slike " -"som wiki eller nettprat) uten å avsløre sin beliggenhet. Ikke bruk dette for " -"å oppnå sterk anonymitet enda." +"En skjult tjeneste lar en {box_name} tilby valgte tjenester (slike som wiki " +"eller nettprat) uten å avsløre sin beliggenhet. Ikke bruk dette for å oppnå " +"sterk anonymitet enda." #: plinth/modules/tor/forms.py:111 msgid "Download software packages over Tor" @@ -7068,13 +7031,11 @@ msgstr "Løktjeneste" msgid "Ports" msgstr "Porter" -#: plinth/modules/tor/views.py:55 -#, fuzzy -#| msgid "An error occurred during configuration." +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" -msgstr "En feil oppsto under konfigureringen." +msgstr "Oppdaterer oppsett" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -7134,7 +7095,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7144,19 +7105,16 @@ msgstr "" "designet for å kunne lese nyheter fra hvor som helst, mens man er så nær en " "virkelig skrivebordsenhet som mulig." -#: plinth/modules/ttrss/__init__.py:27 -#, fuzzy, python-brace-format -#| msgid "" -#| "When enabled, Tiny Tiny RSS can be accessed by any user with a {box_name} login." +#: plinth/modules/ttrss/__init__.py:24 +#, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -"Tiny Tiny RSS er tilgjengelig for enhver bruker med " -"et {box_name}-brukernavn." +"Når aktiv er Tiny Tiny RSS tilgjengelig for enhver " +"bruker som er medlem av gruppen feed-reader." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 #, fuzzy #| msgid "" #| "When using a mobile or desktop application for Tiny Tiny RSS, use the URL " @@ -7168,11 +7126,11 @@ msgstr "" "Når du bruker et mobilbasert- eller skrivebords-program for Tiny Tiny RSS, " "bruk nettadressen /tt-rss-appfor å koble til." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Nyhetstrøm-leser" @@ -7180,12 +7138,12 @@ msgstr "Nyhetstrøm-leser" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (avgreining)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "Sjekk og legg til siste programvare- og sikkerhetsoppdateringer." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7193,39 +7151,35 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 -#, fuzzy -#| msgid "Software Upgrades" msgid "Software Update" -msgstr "Programvare-oppgraderinger" +msgstr "Programvare-oppdatering" -#: plinth/modules/upgrades/__init__.py:130 -#, fuzzy -#| msgid "FreedomBox Foundation" +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" -msgstr "FreedomBox Foundation" +msgstr "FreedomBox oppdatert" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution update started" msgstr "Automatiske oppgraderinger avslått (deaktivert)" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7308,8 +7262,7 @@ msgstr "" " " #: plinth/modules/upgrades/templates/upgrades-new-release.html:9 -#, fuzzy, python-format -#| msgid "%(box_name)s Updated" +#, python-format msgid "%(box_name)s updated" msgstr "%(box_name)s oppdatert" @@ -7411,62 +7364,60 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Automatiske oppgraderinger aktivert" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" "Feil ved oppsett av uoppdaterte oppgraderinger (unattended-upgrades): {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatiske oppgraderinger aktivert" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatiske oppgraderinger avslått (deaktivert)" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 #, fuzzy #| msgid "Automatic upgrades enabled" msgid "Distribution upgrade enabled" msgstr "Automatiske oppgraderinger aktivert" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "Automatic upgrades disabled" msgid "Distribution upgrade disabled" msgstr "Automatiske oppgraderinger avslått (deaktivert)" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Oppgraderingsprosessen (upgrade process) har startet." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Å starte oppgradering (upgrade) mislyktes." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 -#, fuzzy -#| msgid "Automatic upgrades enabled" +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." -msgstr "Automatiske oppgraderinger aktivert" +msgstr "Starter test av distribusjonsoppgradering." -#: plinth/modules/users/__init__.py:29 -#, fuzzy +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" "Opprett og håndter brukerkontoer. Disse kontoene tjener som sentralisert " -"identitetsbekreftelsesmekanisme for de fleste programmer. Noen kan kreve at " -"en brukerkonto er en del av gruppen for å klarere brukrens tilgang til det." +"identitetsbekreftelsesmekanisme for de fleste programmer. Noen programmer " +"kan kreve at en brukerkonto er medlem av en gruppe for å gi brukeren tilgang " +"til programmet." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7477,15 +7428,15 @@ msgstr "" "liste over programmer som er relevante for dem på hjemmesiden. Dog kan kun " "brukere av admin-gruppen endre programmer eller systeminnstillinger." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Brukere og grupper" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Tilgang til alle tjenester og systeminnstillinger" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Sjekk LDAP-oppføring «{search_item}»" @@ -7504,23 +7455,21 @@ msgid "" msgstr "" "Påkrevd. 150 tegn eller mindre. Kun engelske bokstaver, tall og @/./-/_." -#: plinth/modules/users/forms.py:78 -#, fuzzy -#| msgid "Administrator Password" +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" -msgstr "Administratorpassord" +msgstr "Tilgangspassord" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." -msgstr "" +msgstr "Skriv inn passordet for bruker «{user}» for å tillate kontoendringer." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Ugyldig passord." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7534,12 +7483,12 @@ msgstr "" "gruppen kan logge seg på alle tjenester. De kan også logge inn på systemet " "via SSH, og ha administrative rettigheter (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Oppretting av LDAP-bruker mislyktes: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Klarte ikke å legge ny bruker til i {group}-gruppen: {error}" @@ -7558,43 +7507,43 @@ msgstr "" "på systemet uten å bruke passord. Du kan legge inn multiple (flere) nøkler, " "én på hver linje. Blanke linjer og linjer som starter med # vil bli ignorert." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Klarte ikke å bytte navn på LDAP-bruker." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Klarte ikke å slette bruker fra gruppe." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Klarte ikke legge bruker til gruppe." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Klarte ikke sette SSH-nøkler." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add user to group." msgid "Failed to change user status." msgstr "Klarte ikke legge bruker til gruppe." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Klarte ikke å bytte passord for LDAP-bruker." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Klarte ikke å legge til en ny bruker i admin-gruppen: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Klarte ikke å begrense konsolltilgang: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Brukerkonto er opprettet, du er nå logget inn" @@ -7611,12 +7560,12 @@ msgstr "Lagre passord" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Opprett bruker" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Slett bruker" @@ -7657,17 +7606,17 @@ msgid "The following administrator accounts exist in the system." msgstr "Følgende administratorkontoer finnes i systemet." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Brukere" @@ -7700,34 +7649,34 @@ msgstr "" msgid "Save Changes" msgstr "Lagre endringer" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Bruker %(username)s opprettet." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." -msgstr "Bruker %(username)s oppdatert." +msgstr "Oppdaterte bruker %(username)s." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Rediger bruker" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Bruker {user} slettet." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Klarte ikke slette LDAP-bruker." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Endre passord" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Vellykket passordbytte." @@ -8088,7 +8037,7 @@ msgstr "Slett tilkobling" msgid "Server deleted." msgstr "Tjener slettet." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8097,7 +8046,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8106,28 +8055,28 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 #, fuzzy #| msgid "Address" msgid "WordPress" msgstr "Adresse" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki and Blog" msgid "Website and Blog" @@ -8146,7 +8095,7 @@ msgstr "" "nettstedet eller bloggen. Aktiver kun etter at oppsettet av Wordpress er " "gjennomført." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8159,7 +8108,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8167,13 +8116,13 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" -msgstr "Foto-organiserer" +msgstr "Organiserer fotografier" #: plinth/modules/zoph/forms.py:14 msgid "Enable OpenStreetMap for maps" @@ -8210,10 +8159,9 @@ msgid "Generic" msgstr "Generisk" #: plinth/operation.py:116 -#, fuzzy, python-brace-format -#| msgid "Error setting hostname: {exception}" +#, python-brace-format msgid "Error: {name}: {exception_message}" -msgstr "Feil ved setting av vertsnavn: {exception}" +msgstr "Feil: {name}: {exception_message}" #: plinth/operation.py:119 #, python-brace-format @@ -8226,116 +8174,106 @@ msgstr "" msgid "Finished: {name}" msgstr "Tjeneste deaktivert: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Pakke {expression} er ikke tilgjengelig for installasjon" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Pakke {package_name} er siste versjon ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Feil under sikkerhetskopiering" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "installering" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "laster ned" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "mediaendring" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "oppsettsfil: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Installer App-er" -#: plinth/setup.py:42 -#, fuzzy -#| msgid "Updating..." +#: plinth/setup.py:43 msgid "Updating app" -msgstr "Oppdaterer…" +msgstr "Oppdaterer program" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Feil ved programinstallering: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Feil ved programinstallering: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Feil ved programinstallering: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Feil ved programinstallering: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Program installert." -#: plinth/setup.py:87 -#, fuzzy -#| msgid "Last update" +#: plinth/setup.py:88 msgid "App updated" -msgstr "Siste oppdatering" +msgstr "Program oppdatert" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Installer App-er" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Feil ved programinstallering: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Feil ved programinstallering: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Program installert." -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8397,53 +8335,54 @@ msgstr "Installasjon" msgid "Service %(service_name)s is not running." msgstr "Tjenesten %(service_name)s kjører ikke." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Kjernefunksjonalitet og nettbrukergrensesnitt for %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Hjem" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Hjem" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Programmer" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Apps/Programmer" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " System" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "System" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Endre passord" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Slå av" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Logg ut" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Velg språk" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Logg inn" @@ -8501,7 +8440,7 @@ msgstr "Debian:" #: plinth/templates/clients.html:114 msgid "Homebrew:" -msgstr "Hjemmelaget:" +msgstr "Homebrew:" #: plinth/templates/clients.html:117 msgid "RPM:" @@ -8562,7 +8501,7 @@ msgstr "Doner" #: plinth/templates/index.html:139 msgid "FreedomBox Foundation" -msgstr "FreedomBox Foundation" +msgstr "FreedomBox-stiftelsen" #: plinth/templates/index.html:146 msgid "Forum" @@ -8705,10 +8644,9 @@ msgid "Uninstall" msgstr "Installer" #: plinth/templates/uninstall.html:11 -#, fuzzy, python-format -#| msgid "Edit User %(username)s" +#, python-format msgid "Uninstall App %(app_name)s?" -msgstr "Rediger bruker %(username)s" +msgstr "Avinstaller program %(app_name)s?" #: plinth/templates/uninstall.html:17 msgid "Uninstalling an app is an exprimental feature." @@ -8727,12 +8665,51 @@ msgstr "Oppsett uendret" #: plinth/views.py:401 #, python-brace-format msgid "before uninstall of {app_id}" -msgstr "" +msgstr "før avinstallering av {app_id}" #: plinth/web_framework.py:114 msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Aktiver DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Aktiver domenenavnsystemets sikkerhetsutvidelser" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Brannmur-bakgrunnsprosessen kjører ikke. Den må kjøre. Brannmuren kommer " +#~ "som standard aktivert på %(box_name)s. På et Debian-basert system (slik " +#~ "som %(box_name)s), kan du kjøre den med kommandoen «service firewalld " +#~ "start», eller alternativt i et system med systemd, «systemctl start " +#~ "firewalld»." + +#, fuzzy +#~| msgid "Moderate" +#~ msgid "Migrate" +#~ msgstr "Moderat" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "SSH-identitetsbekreftelse med passord avskrudd." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "SSH-autentisering med passord aktivert." + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Feil under sikkerhetskopiering" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Kjernefunksjonalitet og nettbrukergrensesnitt for %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Nettverksoppkoblinger" diff --git a/plinth/locale/nl/LC_MESSAGES/django.po b/plinth/locale/nl/LC_MESSAGES/django.po index e6cf7a9c5..a149d7841 100644 --- a/plinth/locale/nl/LC_MESSAGES/django.po +++ b/plinth/locale/nl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Dutch calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1051,23 +1044,23 @@ msgstr "" "tot deze toepassing. Alle gebruikers met toegang kunnen alle bibliotheken " "gebruiken." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Gebruik calibre e-book bibliotheken" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-boek bibliotheek" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Naam van de nieuwe bibliotheek" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1075,7 +1068,7 @@ msgstr "" "Alleen letters van het Engelse alfabet, cijfers en de tekens _ . en - zonder " "spaties of speciale tekens. Voorbeeld: Mijn_Bibliotheek_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Er bestaat al een bibliotheek met deze naam." @@ -1123,20 +1116,20 @@ msgstr "Ga naar bibliotheek %(library)s" msgid "Delete library %(library)s" msgstr "Verwijder bibliotheek %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Bibliotheek aangemaakt." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Er is een fout opgetreden tijdens het aanmaken van de bibliotheek." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} verwijderd." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Verwijderen van {name} mislukt: {error}" @@ -1184,7 +1177,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Serverbeheer" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1192,18 +1185,18 @@ msgstr "" "Hier kunnen een aantal algemene configuratieopties worden ingesteld, zoals " "hostname, domeinnaam, startpagina etc." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Algemene Instellingen" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Configureer" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1318,48 +1311,48 @@ msgstr "" "Logboeken bevatten informatie over wie toegang heeft gehad tot het systeem " "en foutopsporingsinformatie van verschillende services" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Hostnaam instellen mislukt: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Hostnaam ingesteld" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Domeinnaam instellen mislukt: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Domeinnaam ingesteld" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" "Fout bij het instellen van de startpagina van de webserver: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Startpagina van webserver ingesteld" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Fout bij het wijzigen van de geavanceerde modus: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Geavanceerde toepassingen en functies worden weergeven" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Geavanceerde toepassingen en functies verbergen" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1372,7 +1365,7 @@ msgstr "" "gesprek tot stand te brengen tussen partijen die anders geen verbinding met " "elkaar kunnen maken." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse of ejabberdmoeten worden geconfigureerd met de hier verstrekte details." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP helper" @@ -1444,11 +1437,11 @@ msgstr "Fout bij tijdzone instellen: {exception}" msgid "Time zone set" msgstr "Tijdzone ingesteld" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge is een BitTorrent Cliënt met web-bediening." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1456,16 +1449,16 @@ msgstr "" "Het standaardwachtwoord is 'deluge', maar dit moet zo snel mogelijk na " "activering gewijzigd worden." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Download bestanden met BitTorrent toepassingen" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent-webclient" @@ -1592,7 +1585,7 @@ msgstr "Resultaat" msgid "Diagnostic Test" msgstr "Diagnostische test" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1604,7 +1597,7 @@ msgstr "" "internet. Daardoor is het gebruik van de diensten van {box_name} vaak " "onmogelijk van buiten het lokale netwerk." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1622,7 +1615,7 @@ msgstr "" "naamswijziging doorvoeren, en als iemand op het internet om deze DNS naam " "vraagt wordt dit beantwoord met het juiste IP adres." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1635,11 +1628,11 @@ msgstr "" "diensten van freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Dynamic DNS Cliënt" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dynamische domeinnaam" @@ -1768,7 +1761,7 @@ msgstr "Dit veld is vereist." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1823,7 +1816,7 @@ msgstr "Server weigert verbinding" msgid "Already up-to-date" msgstr "Al bijgewerkt" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1831,7 +1824,7 @@ msgstr "" "XMPP is een open en gestandaardiseerd communicatie protocol. Hiermee kan een " "XMPP server met de naam ejabberd worden ingesteld." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientgebruiker van {box_name} daartoe " "toegang krijgen." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn toepassing of configureer " "een externe server." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Chatserver" @@ -1983,7 +1976,7 @@ msgstr "" "eruit als username@%(domainname)s. Het domein kan worden ingesteld op " "de Instellingen pagina." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1993,7 +1986,7 @@ msgstr "" "Rspamd. Postfix verstuurt en ontvangt e-mails. Met Dovecot hebben e-" "mailclients toegang tot uw mailbox via IMAP en POP3. Rspamd filtert op spam." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -2005,7 +1998,7 @@ msgstr "" "uitgaande e-mail. Sommige heffen de restrictie op na een expliciet verzoek. " "Zie de handleiding pagina voor meer informatie." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2020,7 +2013,7 @@ msgstr "" "adres. Noodzakelijke aliassen zoals \"postmaster\" worden automatisch " "aangemaakt en wijzen naar de eerste admin gebruiker." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2028,7 +2021,7 @@ msgstr "" "Roundcube app biedt gebruikers een " "webinterface om toegang te krijgen tot e-mail." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2159,7 +2152,7 @@ msgstr "Poort" msgid "Host/Target/Value" msgstr "Host/Target/Value" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2170,7 +2163,7 @@ msgstr "" "datastromen van {box_name} stuurt. Een geactiveerde en goed ingestelde " "firewall vermindert het risico op beveiligingsrisico's vanuit internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2190,52 +2183,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Poort {name} ({details}) is niet beschikbaar voor externe netwerken" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Firewall daemon draait niet.De firewall staat standaard aan op %(box_name)s. " -"Op ieder Debian gebaseerd systeem (zoals %(box_name)s) kan het gestart " -"worden door middel van het commando 'service firewalld start' of in het " -"geval van een systeem met systemd 'systemctl start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Dienst/Poort" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Ingeschakeld" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Uitgeschakeld" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Toegestaan" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Toegestaan (alleen intern)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Toegestaan (alleen extern)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Geblokkeerd" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2245,13 +2225,13 @@ msgstr "" "wordt deze ook toegevoegd aan de firewall, en als een dienst wordt " "uitgeschakeld, gebeurt dit ook in de firewall." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Gevorderd" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2304,7 +2284,7 @@ msgstr "Setup starten" msgid "Setup Complete" msgstr "Instelling voltooid" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2323,7 +2303,7 @@ msgstr "" "line als grafische versies beschikbaar). En je kan je broncode delen met " "mensen over de hele wereld." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2331,71 +2311,71 @@ msgstr "" "Bezoek Git tutorial " "voor meer informatie over het gebruik van Git." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Lees- en schrijftoegang tot Git-repositories" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Eenvoudige Git Hosting" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Ongeldige repository URL." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Ongeldige repository naam." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Naam van een nieuwe repository of URL om een bestaande repository te " "importeren." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Beschrijving van de repository" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Optioneel, voor weergave op Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Naam eigenaar repository" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Privérepository" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Geef alleen geautoriseerde gebruikers toegang tot deze repository." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Er bestaat al een repository met deze naam." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Naam van de repository" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" "Een alfanumerieke tekenreeks die op unieke wijze een repository " "identificeert." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Standaard versie" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb geeft dit weer als een standaard branch." @@ -2439,19 +2419,19 @@ msgstr "Verwijder Git Repository %(name)s" msgid "Delete this repository permanently?" msgstr "Deze repository permanent verwijderen?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Repository aangemaakt." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Er is een fout opgetreden bij het aanmaken van de repository." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Repository gewijzigd." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Wijzig repository" @@ -2819,7 +2799,7 @@ msgstr "Over {box_name}" msgid "{box_name} Manual" msgstr "{box_name} Handleiding" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2831,7 +2811,7 @@ msgstr "" "voor anonimiteit door gecodeerd verkeer te sturen via een netwerk dat door " "vrijwilligers over de hele wereld wordt verspreid." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2839,7 +2819,7 @@ msgstr "" "Vind meer informatie over I2P op hun project homepage." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2847,19 +2827,19 @@ msgstr "" "Bij het eerste bezoek aan de meegeleverde webinterface wordt het " "configuratieproces gestart." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "I2P-toepassing beheren" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Anonimiteitsnetwerk" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P proxy" @@ -2905,7 +2885,7 @@ msgstr "" "peer netwerk. Download bestanden door torrents toe te voegen of maak een " "nieuwe torrent om een bestand te delen." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2915,7 +2895,7 @@ msgstr "" "verschillende lichtgewicht markup-talen, met inbegrip van Markdown, en " "algemene blogging functionaliteit zoals reacties en RSS-feeds." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2929,15 +2909,15 @@ msgstr "" "Configuratie kan je deze instellingen wijzigen en nieuwe gebruikers " "registreren." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki en Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Bekijken en bewerken van wiki toepassingen" @@ -2993,43 +2973,43 @@ msgstr "" "Deze actie zal alle bijdragen, pagina's, en commentaar inclusief revisie-" "historie. Deze wiki of blog permanent verwijderen?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Wiki {name} gemaakt." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Kan wiki niet aanmaken: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blog {name} gemaakt." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Kan blog niet aanmaken: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} verwijderd." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Verwijderen van {title} mislukt: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" "infinoted is een server voor Gobby, een tekst-editor voor gezamenlijk " "gebruik." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3040,11 +3020,11 @@ msgstr "" "a> desktop-client en installeer deze. Start Gobby en selecteer vervolgens " "\"Verbinden met Server\" en voer de {box_name} domeinnaam in." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby Server" @@ -3092,7 +3072,7 @@ msgstr "Janus Video Ruimte" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "JavaScript licentie-informatie" @@ -3112,7 +3092,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Chat Cliënt" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3128,7 +3108,7 @@ msgstr "" "van een domein te zijn tegenover Let's Encrypt, een certificaatwaarmerker " "(CA)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3141,15 +3121,15 @@ msgstr "" "\"https://letsencrypt.org/repository/\">Let's Encrypt Subscriber Agreement vóór het gebruik van deze dienst." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certificaten" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Kan niet testen: Er zijn geen domeinen ingesteld." @@ -3214,7 +3194,7 @@ msgstr "" "Er zijn geen geconfigureerde domeinen. Stel " "domeinen in om certificaten ervoor te kunnen uitgeven." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3223,34 +3203,34 @@ msgstr "" "Certificaat met succes ingetrokken voor domein {domain}. Het kan enige tijd " "duren voordat het effect heeft." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Intrekken certificaat voor domein {domain} mislukt: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Certificaat voor domein {domain} met succes verkregen" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Verkrijgen van certificaat voor domein {domain} is mislukt: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Certificaat met succes verwijderd voor domein {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Verwijderen certificaat voor domein {domain} mislukt: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3267,7 +3247,7 @@ msgstr "" "Matrix server kunnen gesprekken aangaan met gebruikers op alle andere Matrix " "servers door federatie (gedecentraliseerd netwerk)." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3277,7 +3257,7 @@ msgstr "" "videogesprekken. Installeer de Coturn " "toepassing of configureer een externe server." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3385,7 +3365,7 @@ msgstr "" "vereist. Ga naar Let's Encrypt om er een " "te verkrijgen." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3398,7 +3378,7 @@ msgstr "" "gebruiken om een wiki website aan te bieden, persoonlijke aantekeningen bij " "te houden of met vrienden aan een gezamenlijke website te werken." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3412,7 +3392,7 @@ msgstr "" "vanuit MediaWiki op de Speciaal:GebruikerRegistreren pagina." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3420,12 +3400,12 @@ msgstr "" "Iedereen met een link naar deze wiki kan hem lezen. Alleen ingelogde " "gebruikers kunnen wijzigingen aanbrengen in de inhoud." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3507,35 +3487,35 @@ msgstr "Wachtwoord bijgewerkt" msgid "Password update failed. Please choose a stronger password" msgstr "Wachtwoordupdate mislukt. Kies een sterker wachtwoord" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Openbare registraties ingeschakeld" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Openbare registraties uitgeschakeld" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Privé-modus ingeschakeld" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Privé-modus uitgeschakeld" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Standaard uiterlijk veranderd" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Domeinnaam bijgewerkt" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Sitenaam bijgewerkt" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3548,11 +3528,11 @@ msgstr "" "standaardpoort (30000). Voor de verbinding met de server is een Minetest client nodig." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Block Sandbox" @@ -3604,7 +3584,7 @@ msgstr "Indien uitgeschakeld, kunnen spelers niet sterven of schade oplopen." msgid "Address" msgstr "Adres" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3792,7 +3772,7 @@ msgstr "Secure Shell" msgid "Services" msgstr "Diensten" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3800,7 +3780,7 @@ msgstr "" "Stel netwerkapparaten in. Maak verbinding met internet via Ethernet, Wi-Fi " "of PPPoE. Deel die verbinding met andere apparaten op het netwerk." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3808,7 +3788,7 @@ msgstr "" "Apparaten die via andere methoden worden beheerd, zijn hier mogelijk niet " "beschikbaar voor configuratie." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Netwerken" @@ -4245,7 +4225,7 @@ msgstr "Wijzig verbinding" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Wijzig" @@ -4350,7 +4330,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Methode" @@ -4366,7 +4346,7 @@ msgstr "DNS server" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Standaard" @@ -4379,7 +4359,7 @@ msgid "This connection is not active." msgstr "Deze verbinding is niet actief." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Security" @@ -4965,7 +4945,7 @@ msgstr "Verbinding {name} verwijderd." msgid "Failed to delete connection: Connection not found." msgstr "Kan verbinding niet verwijderen: Verbinding niet gevonden." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4983,20 +4963,20 @@ msgstr "" "mogelijk om de rest van het internetgebruik via {box_name} te leiden, voor " "meer veiligheid en anonimiteit." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Verbinding maken met VPN-dienst" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Virtual Private Network" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5007,58 +4987,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Migreer naar ECC" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Je OpenVPN-installatie gebruikt momenteel RSA. Overschakelen naar de moderne " -"Elliptic Curve Cryptography verbetert de snelheid van het tot stand brengen " -"van een verbinding en de beveiliging. Deze operatie is onomkeerbaar. Dit zou " -"slechts enkele minuten moeten duren op de meeste single board computers." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Alle nieuwe installaties van OpenVPN op %(box_name)s zullen standaard ECC " -"gebruiken. We raden aan om zo snel mogelijkover te stappen." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Waarschuwing: Bestaande clientprofielen worden door deze bewerking " -"ongeldig gemaakt. Alle OpenVPN-gebruikers op %(box_name)s moeten nieuwe " -"profielen downloaden. Om verbinding te maken met deze server moet een " -"OpenVPN-client die compatibel is met ECC worden gebruikt." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migreren" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profiel" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Om te verbinden met de VPN van %(box_name)s moet een profiel worden " @@ -5067,17 +5010,18 @@ msgstr "" "platformen. Klik op \"Meer info...\" hierboven voor aanbevolen programma's " "en gebruiksinstructies." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Profielen zijn voor iedere gebruiker van %(box_name)s anders. Houd ze geheim." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Download mijn profiel" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5090,19 +5034,19 @@ msgstr "" "vereist als de diensten op {box_name} niet te bereiken zijn vanaf de rest " "van internet. Dit is het geval in de volgende situaties:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} is verbonden achter een beperkende firewall." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} is verbonden met een (wireless) router die niet onder eigen " "controle staat." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5110,7 +5054,7 @@ msgstr "" "De internetprovider geeft geen extern IP adres maar maakt gebruik van een " "NAT verbinding." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5118,11 +5062,11 @@ msgstr "" "De internetprovider geeft geen statisch IP adres, en het IP adres verandert " "telkens wanneer je verbinding maakt met internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "De internetprovider beperkt inkomende verbindingen." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5136,23 +5080,23 @@ msgstr "" "\">pagekite.net. In de toekomst is het misschien mogelijk om de " "{box_name} van een van je vrienden te gebruiken." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Openbare zichtbaarheid" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite domein" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Serverdomein" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5160,31 +5104,31 @@ msgstr "" "Selecteer een pagekite server. Gebruik \"pagekite.net\" om de standaard " "pagekite.net server te gebruiken." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Serverpoort" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Poort voor de pagekite server (default: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kitenaam" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Voorbeeld: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Foute kite-naam" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite-geheim" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5192,35 +5136,35 @@ msgstr "" "Het wachtwoord dat met deze kite is verbonden, en het standaard wachtwoord " "voor deze account als deze kite geen eigen wachtwoord heeft." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protocol" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "externe (frontend) poort" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "interne (freedombox) poort" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Subdomeinen Inschakelen" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Verwijderde aangepaste dienst" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Deze dienst is al beschikbaar als een standaarddienst." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Aangepaste dienst toevoegen" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Deze dienst bestaat al" @@ -5258,31 +5202,31 @@ msgstr "" "bijvoorbeeld bekend dat HTTPS servers die niet op poort 443 worden ingesteld " "problemen opleveren." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Webserver (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" "De website zal beschikbaar zijn op http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Webserver (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" "De website zal beschikbaar zijn op https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5334,8 +5278,8 @@ msgstr "" "Er wordt nu een installatie of upgrade uitgevoerd. Wacht alstublieft tot dit " "voltooid is voordat je het apparaat herstart of uitzet." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Herstarten" @@ -5385,6 +5329,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Nu Uitschakelen" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5425,7 +5402,7 @@ msgstr "Web Proxy" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Gebruik {url} via proxy {proxy} op tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5443,7 +5420,7 @@ msgstr "" "mobiele telefoon kunnen worden gebruikt om te verbinden of de verbinding te " "verbreken." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your desktop en mobiele apparaten." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC Cliënt" @@ -5467,7 +5444,7 @@ msgstr "IRC Cliënt" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5482,7 +5459,7 @@ msgstr "" "\">ondersteunde clienttoepassing nodig. Radicale kan worden benaderd " "door elke {box_name} gebruiker." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5493,12 +5470,12 @@ msgstr "" "gebeurtenissen of contactpersonen, die moeten worden gedaan met behulp van " "een aparte client." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Agenda en Adresboek" @@ -5572,7 +5549,7 @@ msgstr "" "freedombox.address>) en je gebruikersnaam. Klikken op de zoekknop zal de " "bestaande kalenders en adresboeken weergeven." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Configuratie van de toegangsrechten is bijgewerkt" @@ -5663,7 +5640,7 @@ msgstr "" "verschillende websites te volgen. Schakel bij het toevoegen van een feed " "authenticatie in en gebruik de {box_name}-inloggegevens." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Lezen en abonneren op nieuwsfeeds" @@ -5676,7 +5653,7 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "RSS Feed Generator" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5684,7 +5661,7 @@ msgstr "" "Met Samba kunnen bestanden en mappen worden gedeeld tussen FreedomBox en " "andere computers in het lokale netwerk." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5698,11 +5675,11 @@ msgstr "" "smb://{hostname}.local (op Linux en Mac). Er zijn drie soorten van delen " "waaruit gekozen kan worden: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Open deelmap - toegankelijk voor iedereen in het lokale netwerk." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5710,7 +5687,7 @@ msgstr "" "Groeps deelmap - alleen toegankelijk voor FreedomBox-gebruikers die deel " "uitmaken van de freedombox-share-groep." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5718,15 +5695,15 @@ msgstr "" "Prive-deelmap - - iedere gebruiker in de freedombox-share-groep kan zijn " "eigen privéruimte hebben." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Toegang tot de privéshares" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Netwerk bestandenopslag" @@ -5815,15 +5792,15 @@ msgstr "Gedeelde map naam" msgid "Action" msgstr "Actie" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS-schijf" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Gedeelde map openen" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Gedeelde map" @@ -5849,7 +5826,7 @@ msgstr "Gedeelde map uitgeschakeld." msgid "Error disabling share: {error_message}" msgstr "Fout bij het uitschakelen van de gedeelde map: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5857,7 +5834,7 @@ msgstr "" "Searx is een privacy-respecterende internet metasearch engine. Het " "aggregeert en toont resultaten van meerdere zoekmachines." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5865,39 +5842,39 @@ msgstr "" "Searx kan worden gebruikt om tracking en profilering door zoekmachines te " "voorkomen. Het slaat standaard geen cookies op." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Zoeken op internet" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Zoeken op het Internet" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Veilig Zoeken" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "Kies het standaard familiefilter om toe te passen op zoekresultaten." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Modereren" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Strikt" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Openbare toegang toestaan" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Sta toe dat deze toepassing wordt gebruikt door iedereen die er toegang toe " @@ -6078,7 +6055,7 @@ msgstr "Bladwijzers" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6088,7 +6065,7 @@ msgstr "" "beschermen. Het kan gebruikt worden om censuur en het filteren van Internet " "te omzeilen." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6101,7 +6078,7 @@ msgstr "" "Apparaten in het lokale netwerk kunnen met deze proxy verbinden, en hun data " "zal versleuteld via de Shadowsocks server verstuurd worden." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6110,42 +6087,42 @@ msgstr "" "proxy in op het apparaat, webbrowser of toepassing naar http://" "adres_van_de_freedombox:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Socks5 Proxy" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Aanbevolen" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Server" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Server hostnaam of IP adres" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Server poortnummer" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Wachtwoord dat wordt gebruikt om gegevens te coderen. Moet overeenkomen met " "serverwachtwoord." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Encryptie methode. Moet overeenkomen met de instelling van de server." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6154,15 +6131,15 @@ msgstr "" "Delen maakt het mogelijk om bestanden en mappen op {box_name} te delen via " "het Internet met door jou bepaalde gebruikers." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Delen" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Naam van de gedeelde bron" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6170,27 +6147,27 @@ msgstr "" "Een aaneengesloten reeks van kleine letters en/of cijfers, die " "bestandsdeling aanduidt. Bijvoorbeeld: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Te delen pad" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Pad naar een map op deze server die je wilt delen." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Openbare share" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Bestanden in deze map beschikbaar maken voor iedereen met de link." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Gebruikersgroepen die de bestanden in de share kunnen lezen:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6198,11 +6175,11 @@ msgstr "" "Gebruikers in de geselecteerde gebruikersgroepen kunnen de bestanden in de " "share lezen." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Er bestaat reeds een gedeelde map met deze naam." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Shares moeten openbaar zijn of gedeeld worden met minimaal één groep" @@ -6239,19 +6216,19 @@ msgstr "Gedeelde map toegevoegd." msgid "Add Share" msgstr "Gedeelde map toevoegen" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Gedeelde map bewerkt." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Gedeelde map bewerken" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Gedeelde map verwijderd." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6261,7 +6238,7 @@ msgstr "" "kunnen worden gebruikt om in geval van ongewenste wijzigingen aan het " "systeem terug te keren naar een voorheen goed werkende staat." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6272,7 +6249,7 @@ msgstr "" "voor en na een software-installatie. Oudere Snapshots worden automatisch " "opgeschoond volgens de onderstaande instellingen." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups aangezien ze op dezelfde partitie als hun bron worden " "bewaard. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Opslag Snapshots" @@ -6386,7 +6363,7 @@ msgstr "Datum" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Snapshots verwijderen" @@ -6440,58 +6417,58 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Terugdraaien tot Snapshot #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "handmatig gemaakt" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "tijdlijn" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Beheren van Snapshots" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Gemaakte snapshot." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Opslag van Snapshots configuratie is bijgewerkt" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Actiefout: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Verwijderde geselecteerde snapshots" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Snapshot is momenteel in gebruik. Probeer het later nog eens." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Teruggezet naar snapshot #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" "Het systeem moet opnieuw worden opgestart om het terugdraaien te voltooien." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Terugdraaien naar Snapshot" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6503,7 +6480,7 @@ msgstr "" "andere locatie die daarvoor geautoriseerd is, kan beheerdertaken uitvoeren, " "bestanden kopiëren en andere taken verrichten door zulk een verbinding." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Secure Shell (SSH) Server" @@ -6541,14 +6518,6 @@ msgstr "Algoritme" msgid "Fingerprint" msgstr "Vingerafdruk" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "SSH-authenticatie met wachtwoord uitgeschakeld." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "SSH-authenticatie met wachtwoord ingeschakeld." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Eenmalige aanmelding" @@ -6561,7 +6530,7 @@ msgstr "Aanmelding" msgid "Logged out successfully." msgstr "Succesvol uitgelogd." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6573,109 +6542,109 @@ msgstr "" "bekijken, verwijderbare media koppelen en ontkoppelen, de rootpartitie " "uitbreiden enz." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Storage" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bytes" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "De bewerking is mislukt." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "De bewerking is afgebroken." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Het apparaat is al aan het ontkoppelen." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "De bewerking wordt niet ondersteund vanwege ontbrekende driver / programma-" "ondersteuning." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Er is een time-out opgetreden voor deze bewerking." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" "De operatie zou een schijf wakker maken die in \"diepe slaap\" stand is." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Poging om een apparaat te ontkoppelen dat in gebruik is." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "De bewerking is al geannuleerd." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Niet gemachtigd om deze handeling uit te voeren." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Het apparaat is al gekoppeld." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Het apparaat is niet ge-mount." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Het is niet toegestaan de gevraagde optie te gebruiken." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Het apparaat is door een andere gebruiker aangekoppeld." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Weinig ruimte op de systeempartitie: {percent_used} % gebruikt, {free_space} " "vrij." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Weinig schijfruimte" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Schijffout dreigt" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6684,39 +6653,39 @@ msgstr "" "Schijf {id} meldt dat het waarschijnlijk in de nabije toekomst defect zal " "zijn. Kopieer alle gegevens terwijl het nog kan en vervang de schijf." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Ongeldige mapnaam." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Map bestaat niet." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Pad is geen map." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Map is niet leesbaar door de gebruiker." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Map is niet schrijfbaar door de gebruiker." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Opslagmap" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Submap (optioneel)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Delen" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Andere map (hieronder aangeven)" @@ -6753,7 +6722,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Root-partitie uitbreiden" @@ -6776,30 +6745,30 @@ msgstr "" "zal %(expandable_root_size)s extra vrije ruimte in de root-partitie " "beschikbaar zijn." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Fout bij partitie uitbreiden: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Partitie succesvol uitgebreid." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} kan veilig worden losgekoppeld." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Het apparaat kan veilig worden losgekoppeld." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Fout bij verwijderen van apparaat: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6812,7 +6781,7 @@ msgstr "" "zullen automatisch dezelfde veranderingen ondergaan op de andere apparaten " "waarop Syncthing draait." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6830,20 +6799,20 @@ msgstr "" "{box_name} is alleen beschikbaar voor gebruikers die tot de \"admin\"- of de " "\"syncthing-access\"-groep behoren." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Beheer Syncthing toepassing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Bestandssynchronisatie" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6857,7 +6826,7 @@ msgstr "" "de Tor " "Browser aan." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6866,40 +6835,40 @@ msgstr "" "Een Tor SOCKS poort is beschikbaar op {box_name} voor interne netwerken op " "TCP poort 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor-Onion Dienst" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor Socks Proxy" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor Bridge Relay" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor relay poort beschikbaar" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 transport geregistreerd" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 transport geregistreerd" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Gebruik URL {url} op tcp{kind} via Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Bevestig Tor gebruik met {url} via tcp{kind}" @@ -7022,11 +6991,11 @@ msgstr "Onion Service" msgid "Ports" msgstr "Poorten" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Configuratie bijwerken" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Fout bij het configureren van de toepassing: {error}" @@ -7088,7 +7057,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7098,7 +7067,7 @@ msgstr "" "om het lezen van nieuws vanaf iedere locatie mogelijk te maken, terwijl het " "zoveel mogelijk als een echte desktoptoepassing wil werken." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7107,7 +7076,7 @@ msgstr "" "Indien ingeschakeld, kan Tiny Tiny RSS worden geopend door elke gebruiker die tot de feed-reader groep behoort." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7115,11 +7084,11 @@ msgstr "" "Gebruik de URL /tt-rss-app in om te verbinden " "met een mobiele- of desktoptoepassing voor Tiny Tiny RSS." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "News Feed Reader" @@ -7127,13 +7096,13 @@ msgstr "News Feed Reader" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Controleer de nieuwste software- en beveiligingsupdates en pas deze toe." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7146,22 +7115,22 @@ msgstr "" "het systeem opnieuw moet worden opgestart, gebeurt dit automatisch om 02:00 " "uur, waardoor alle toepassingen even niet beschikbaar zijn." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Software bijwerken" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox geaktualiseerd" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Kan distributie-update niet starten" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7171,11 +7140,11 @@ msgstr "" "te starten. Zorg ervoor dat ten minste 5 GB ruimte vrij is. Als " "ingeschakeld, wordt de distributie-update na 24 uur opnieuw geprobeerd." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Distributie-update gestart" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "Update naar volgende stabiele release gestart. Dit kan lang duren." @@ -7353,44 +7322,44 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Test de distributie-upgrade nu" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Fout bij het instellen van automatische upgrades: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatisch bijwerken ingeschakeld" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatisch bijwerken uitgeschakeld" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Distributie bijwerken ingeschakeld" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Distributie bijwerken uitgeschakeld" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Upgrade-proces gestart." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Starten van de upgrade is mislukt." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Tussentijdse Software Updates zijn ingeschakeld." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Start de distributie upgrade test." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7401,7 +7370,7 @@ msgstr "" "apps moet een gebruikersaccount deel uitmaken van een groep om de gebruiker " "toegang te geven tot de toepassing." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7413,15 +7382,15 @@ msgstr "" "die lid zijn van de admin -groep mogen toepassings- of " "systeeminstellingen wijzigen." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Gebruikers en Groepen" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Toegang tot alle diensten en systeeminstellingen" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Zoek LDAP item \"{search_item}\"" @@ -7439,11 +7408,11 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "Vereist. 150 tekens of minder. Alleen letters, cijfers en @/./-/_ ." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Authorisatie-wachtwoord" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7451,11 +7420,11 @@ msgstr "" "Voer het wachtwoord voor gebruiker \"{user}\" in om accountwijzigingen toe " "te staan." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Ongeldig wachtwoord." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7470,12 +7439,12 @@ msgstr "" "ook op het systeem inloggen met SSH en kunnen systeemadministratie doen " "(sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "LDAP gebruiker aanmaken mislukt: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Toevoegen van gebruiker aan groep {group} mislukt: {error}" @@ -7495,41 +7464,41 @@ msgstr "" "meerdere sleutels toevoegen, één op elke regel. Lege regels en regels die " "beginnen met # worden genegeerd." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "LDAP gebruiker hernoemen mislukt." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Gebruiker uit groep verwijderen mislukt." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Gebruiker aan groep toevoegen mislukt." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Kan de SSH-sleutels niet instellen." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Gebruikerstatus aanpassen mislukt." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Wijzigen LDAP gebruikerswachtwoord mislukt." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Toevoegen van gebruiker aan admin groep mislukt: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Consoletoegang beperken is mislukt: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Gebruikersaccount aangemaakt, je bent nu ingelogd" @@ -7546,12 +7515,12 @@ msgstr "Wachtwoord Opslaan" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Nieuwe gebruiker registreren" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Gebruiker verwijderen" @@ -7592,13 +7561,19 @@ msgid "The following administrator accounts exist in the system." msgstr "De volgende beheerprofielen bestaan in het systeem." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Verwijder deze accounts door middel van de opdrachtregel en vernieuw de " "pagina om een account aan te maken dat te gebruiken is met %(box_name)s. " @@ -7607,7 +7582,7 @@ msgstr "" "account al bruikbaar is bij %(box_name)s." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Gebruikers" @@ -7640,34 +7615,34 @@ msgstr "" msgid "Save Changes" msgstr "Wijzigingen opslaan" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Gebruiker %(username)s aangemaakt." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Gebruiker %(username)s bijgewerkt." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Gebruiker wijzigen" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Gebruiker {user} verwijderd." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Verwijderen van LDAP gebruiker mislukt." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Wijzig wachtwoord" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Wachtwoord succesvol gewijzigd." @@ -8008,7 +7983,7 @@ msgstr "Verwijder verbinding met server" msgid "Server deleted." msgstr "Server verwijderd." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8022,7 +7997,7 @@ msgstr "" "met thema's. De website en het beheer ervan is bruikbaar met een mobiel " "apparaat." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8035,7 +8010,7 @@ msgstr "" "{box_name} opent met de juiste domeinnaam. Schakel permalinks in de " "beheerdersinterface in voor betere URL's naar uw pagina's en berichten." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8046,7 +8021,7 @@ msgstr "" "\"/wordpress/wp-admin/\">administratie pagina om in de toekomst de " "administratie interface te bereiken." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8056,12 +8031,12 @@ msgstr "" "vanuit de beheerdersinterface. Extra plug-ins of thema's kunnen op eigen " "risico worden geïnstalleerd en geüpgraded." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Website en Blog" @@ -8078,7 +8053,7 @@ msgstr "" "WordPress-site of blog bekijken. Alleen inschakelen na het uitvoeren van de " "eerste WordPress-configuratie." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8100,7 +8075,7 @@ msgstr "" "van zoekwoorden, kaart- en kalenderweergaven. Individuele foto's kunnen met " "anderen worden gedeeld door een directe link te sturen." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8111,11 +8086,11 @@ msgstr "" "Zoph. Voor extra gebruikers moeten zowel in {box_name} als in Zoph accounts " "worden aangemaakt met dezelfde gebruikersnaam." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Foto Organisator" @@ -8169,96 +8144,92 @@ msgstr "Wachten om te starten: {name}" msgid "Finished: {name}" msgstr "Klaar: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Pakket {expression} is niet beschikbaar voor installatie" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Pakket {package_name} is de nieuwste versie ({latest_version})" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "Fout bij het uitvoeren van apt-get" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "installeren" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "downloaden" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "media wijzigen" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "configuratiebestand: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Time-out wachtend op pakketbeheerder" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Toepassing installeren" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Toepassing updaten" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Fout bij het installeren van de toepassing: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Fout bij het bijwerken van de toepassing: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Fout bij het installeren van de toepassing: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Fout bij het bijwerken van de toepassing: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "De toepassing is geïnstalleerd." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "Toepassing bijgewerkt" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Toepassing wordt verwijderd" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Fout bij het verwijderen van de toepassing: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Fout bij het verwijderen van de toepassing: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "De toepassing is verwijderd." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Toepassings-pakketten bijwerken" @@ -8318,53 +8289,54 @@ msgstr "Installatie" msgid "Service %(service_name)s is not running." msgstr "Service %(service_name)s is niet actief." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Basisfunctionaliteit en webinterface voor %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Startpagina" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Startpagina" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Toepassingen" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Toepassingen" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Systeem" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Systeem" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Wijzig wachtwoord" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Uitschakelen" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Afmelden" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Selecteer taal" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Aanmelden" @@ -8653,6 +8625,75 @@ msgstr "voor het verwijderen van {app_id}" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "DNSSEC Inschakelen" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Domeinnaamsysteem beveiliging-extensies inschakelen" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Firewall daemon draait niet.De firewall staat standaard aan op " +#~ "%(box_name)s. Op ieder Debian gebaseerd systeem (zoals %(box_name)s) kan " +#~ "het gestart worden door middel van het commando 'service firewalld start' " +#~ "of in het geval van een systeem met systemd 'systemctl start firewalld'." + +#~ msgid "Migrate to ECC" +#~ msgstr "Migreer naar ECC" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Je OpenVPN-installatie gebruikt momenteel RSA. Overschakelen naar de " +#~ "moderne Elliptic Curve Cryptography verbetert de snelheid van het tot " +#~ "stand brengen van een verbinding en de beveiliging. Deze operatie is " +#~ "onomkeerbaar. Dit zou slechts enkele minuten moeten duren op de meeste " +#~ "single board computers." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Alle nieuwe installaties van OpenVPN op %(box_name)s zullen standaard ECC " +#~ "gebruiken. We raden aan om zo snel mogelijkover te stappen." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Waarschuwing: Bestaande clientprofielen worden door deze bewerking " +#~ "ongeldig gemaakt. Alle OpenVPN-gebruikers op %(box_name)s moeten nieuwe " +#~ "profielen downloaden. Om verbinding te maken met deze server moet een " +#~ "OpenVPN-client die compatibel is met ECC worden gebruikt." + +#~ msgid "Migrate" +#~ msgstr "Migreren" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "SSH-authenticatie met wachtwoord uitgeschakeld." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "SSH-authenticatie met wachtwoord ingeschakeld." + +#~ msgid "Error running apt-get" +#~ msgstr "Fout bij het uitvoeren van apt-get" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Basisfunctionaliteit en webinterface voor %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Netwerkverbindingen" diff --git a/plinth/locale/pl/LC_MESSAGES/django.po b/plinth/locale/pl/LC_MESSAGES/django.po index bc37e252a..dc4f13006 100644 --- a/plinth/locale/pl/LC_MESSAGES/django.po +++ b/plinth/locale/pl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Polish calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Create new repository" msgid "Name of the new library" msgstr "Utwórz nowe repozytorium" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 #, fuzzy #| msgid "Remote backup repository already exists." msgid "A library with this name already exists." @@ -1118,22 +1111,22 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "Repository removed." msgid "Library created." msgstr "Usunięto repozytorium." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "Usunięto {name}." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1177,7 +1170,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Administracja serwera" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1185,18 +1178,18 @@ msgstr "" "Tutaj możesz ustawić kilka ogólnych opcji konfiguracji, takich jak nazwa " "hosta, nazwa domeny, strona główna serwera www itp." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Ustawienia główne" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Konfiguruj" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1306,47 +1299,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Błąd podczas ustawiania nazwy hosta: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Nazwa hosta ustawiona" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Błąd ustawiania nazwy domeny {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Nazwa domeny ustawiona" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Błąd podczas ustawiania strony domowej serwera web: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Ustawiono stronę domową serwera web" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Błąd podczas zmiany trybu zaawansowanego: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Wyświetlanie zaawansowanych aplikacji i cech" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Ukrywanie zaawansowanych aplikacji i cech" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1354,7 +1347,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as freedns." "afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Klient Dynamic DNS" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dynamiczna nazwa domeny" @@ -1760,7 +1753,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1825,7 +1818,7 @@ msgstr "" msgid "Already up-to-date" msgstr "Ostatnie uaktualnienie" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1833,7 +1826,7 @@ msgstr "" "XMPP jest otwartym i ustandaryzowanym protokołem komunikacyjnym. Tu możesz " "uruchomić i skonfigurować własny serwer XMPP zwany ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientklienta XMPP. Gdy włączony, ejabberd jest " "dostępny dla każdego użytkownika {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Serwer czatu" @@ -1973,14 +1966,14 @@ msgstr "" "i>. Możesz ustawić swoją domenę na stronie Konfiguruj." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1988,7 +1981,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1998,13 +1991,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2145,7 +2138,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2156,7 +2149,7 @@ msgstr "" "ruch sieciowy na twoim {box_name}. Włączony i poprawnie skonfigurowany " "firewall redukuje ryzyko zagrożeń z Internetu." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2176,52 +2169,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Proces firewalla nie jest uruchomiony. Proszę go włączyć. Firewall jest " -"domyślnie włączony na %(box_name)s. Na każdym systemie bazującym na Debianie " -"(jak %(box_name)s) możesz go włączyć używając komendy 'service firewalld " -"start' lub, w przypadku systemu z systemd 'systemctl start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Usługa/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Włączony" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Wyłączony" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Zezwolono" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Zezwolono (tylko wewnętrzne)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Zezwolono (tylko zewnętrzne)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Zablokowano" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2231,13 +2211,13 @@ msgstr "" "automatycznie przepuszczana przez firewall a gdy jest wyłączona, jest " "również blokowana przez firewall." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2285,7 +2265,7 @@ msgstr "Rozpocznij" msgid "Setup Complete" msgstr "Instalacja zakończona" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2296,37 +2276,37 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository URL." msgstr "Niewłaściwa nazwa hosta" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "Niewłaściwa nazwa hosta" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 #, fuzzy #| msgid "" #| "Repository path is neither empty nor is an existing backups repository." @@ -2334,55 +2314,55 @@ msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Ścieżka repozytorium jest pusta lub nie jest repozytorium kopii zapasowych." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 #, fuzzy #| msgid "Create new repository" msgid "Description of the repository" msgstr "Utwórz nowe repozytorium" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 #, fuzzy #| msgid "Repository removed." msgid "Repository's owner name" msgstr "Usunięto repozytorium." -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create Repository" msgid "Private repository" msgstr "Utwórz repozytorium" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 #, fuzzy #| msgid "Remote backup repository already exists." msgid "A repository with this name already exists." msgstr "Zdalne repozytorium już istnieje." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Create new repository" msgid "Name of the repository" msgstr "Utwórz nowe repozytorium" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Setting unchanged" msgid "Default branch" msgstr "Ustawienie bez zmian" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2433,23 +2413,23 @@ msgstr "Usuń wiki lub blog %(name)s" msgid "Delete this repository permanently?" msgstr "Usunąć trwale to archiwum?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 #, fuzzy #| msgid "Repository removed." msgid "Repository created." msgstr "Usunięto repozytorium." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 #, fuzzy #| msgid "Repository removed." msgid "Repository edited." msgstr "Usunięto repozytorium." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Create Repository" msgid "Edit repository" @@ -2767,7 +2747,7 @@ msgstr "O {box_name}" msgid "{box_name} Manual" msgstr "{box_name} Podręcznik" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2775,35 +2755,35 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy #| msgid "Enable application" msgid "Manage I2P application" msgstr "Aktywuj aplikację" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 #, fuzzy #| msgid "Go to Networks" msgid "Anonymity Network" msgstr "Przejdź do sieci" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2840,14 +2820,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2856,15 +2836,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki i blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 #, fuzzy #| msgid "Services and Applications" msgid "View and edit wiki applications" @@ -2922,41 +2902,41 @@ msgstr "" "Ta akcja spowoduje usunięcie wszystkich postów, stron oraz komentarzy - w " "tym historii zmian. Trwale usunąć wiki lub blog?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} zostało usunięte." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2964,11 +2944,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -3014,7 +2994,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Informacje o licencji JavaScript" @@ -3034,7 +3014,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Klient czatu" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3044,7 +3024,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3052,15 +3032,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certyfikaty" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3125,41 +3105,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3169,14 +3149,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3259,7 +3239,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3267,7 +3247,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3276,18 +3256,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3366,49 +3346,49 @@ msgstr "Hasło" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 #, fuzzy #| msgid "Application installed." msgid "Public registrations enabled" msgstr "Aplikacja zainstalowania." -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 #, fuzzy #| msgid "Application installed." msgid "Public registrations disabled" msgstr "Aplikacja zainstalowania." -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 #, fuzzy #| msgid "Application enabled" msgid "Private mode enabled" msgstr "Aplikacja włączona" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy #| msgid "Application disabled" msgid "Private mode disabled" msgstr "Aplikacja wyłączona" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 #, fuzzy #| msgid "Setting unchanged" msgid "Default skin changed" msgstr "Ustawienie bez zmian" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "Nazwa domeny ustawiona" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "Nazwa domeny ustawiona" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3417,11 +3397,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 #, fuzzy #| msgid "Blocked" msgid "Block Sandbox" @@ -3468,7 +3448,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3639,19 +3619,19 @@ msgstr "" msgid "Services" msgstr "Urządzenie" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3999,7 +3979,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -4104,7 +4084,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -4120,7 +4100,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -4133,7 +4113,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4691,7 +4671,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4702,22 +4682,22 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection refused" msgid "Connect to VPN services" msgstr "Odmowa dostępu" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4727,61 +4707,29 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4790,33 +4738,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4825,87 +4773,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4939,29 +4887,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5005,8 +4953,8 @@ msgstr "" "Obecnie uruchomiona jest instalacja lub aktualizacja. Poczekaj aż się " "skończy przed ponownym uruchomieniem lub wyłączeniem." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Uruchom ponownie" @@ -5053,6 +5001,39 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5084,7 +5065,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5095,7 +5076,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -5115,7 +5096,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5125,19 +5106,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5198,7 +5179,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Zaktualizowano ustawienia praw dostępu" @@ -5272,7 +5253,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5285,13 +5266,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5300,31 +5281,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5406,17 +5387,17 @@ msgstr "" msgid "Action" msgstr "Akcje" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5446,51 +5427,51 @@ msgstr "Aplikacja wyłączona" msgid "Error disabling share: {error_message}" msgstr "Błąd wyłączenia udziału: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5653,14 +5634,14 @@ msgstr "" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5669,99 +5650,99 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 #, fuzzy #| msgid "Chat Server" msgid "Server" msgstr "Serwer czatu" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5798,26 +5779,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5825,14 +5806,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5934,7 +5915,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 #, fuzzy #| msgid "Delete %(name)s" msgid "Delete Snapshots" @@ -5984,65 +5965,65 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Repository removed." msgid "manually created" msgstr "Usunięto repozytorium." -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 #, fuzzy #| msgid "Delete %(name)s" msgid "Manage Snapshots" msgstr "Usuń %(name)s" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 #, fuzzy #| msgid "Access rights configuration updated" msgid "Storage snapshots configuration updated" msgstr "Zaktualizowano ustawienia praw dostępu" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 #, fuzzy #| msgid "Delete %(name)s" msgid "Deleted selected snapshots" msgstr "Usuń %(name)s" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6050,7 +6031,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -6087,16 +6068,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -#, fuzzy -#| msgid "Authentication to remote server failed." -msgid "SSH authentication with password enabled." -msgstr "Nie powiodła się autoryzacja na zdalnym serwerze." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6111,7 +6082,7 @@ msgstr "" msgid "Logged out successfully." msgstr "Partycja rozszerzona." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6119,147 +6090,147 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bajtów" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 #, fuzzy #| msgid "The requested domain is already registered." msgid "The device is already mounted." msgstr "Wnioskowana domena jest już zarejstrowana." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "Niewłaściwa nazwa hosta" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6299,7 +6270,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Rozszerz główną partycję" @@ -6319,30 +6290,30 @@ msgstr "" "Proszę najpierw utworzyć kopię bezpieczeństwa. Po tej operacji twoja główna " "partycja będzie zwiększona o %(expandable_root_size)s." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Błąd rozszerzania partycji: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Partycja rozszerzona." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6350,7 +6321,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6362,20 +6333,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6384,47 +6355,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6526,13 +6497,13 @@ msgstr "Usługa dynamicznego DNS" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Podczas konfiguracji wystąpił błąd." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6590,14 +6561,14 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS can be accessed by any użytkownik za pomocą {box_name} loginu " "może mieć dostęp do Tiny Tiny RSS, gdy ten jest włączony." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6627,12 +6598,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6640,8 +6611,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -6649,30 +6620,30 @@ msgstr "" msgid "Software Update" msgstr "Archiwum zostało usunięte." -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox Foundation" msgid "FreedomBox Updated" msgstr "Fundacja FreedomBox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "User registrations disabled" msgid "Distribution update started" msgstr "Rejestracja użytkowników wyłączona" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6836,55 +6807,55 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Rejestracja użytkowników wyłączona" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "User registrations disabled" msgid "Distribution upgrade disabled" msgstr "Rejestracja użytkowników wyłączona" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "User registrations disabled" msgid "Starting distribution upgrade test." msgstr "Rejestracja użytkowników wyłączona" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6892,15 +6863,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6920,25 +6891,25 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 #, fuzzy #| msgid "Administrator Account" msgid "Authorization Password" msgstr "Konto Administratora" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Show password" msgid "Invalid password." msgstr "Pokaż hasło" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6947,12 +6918,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Tworzenie użytkownika LDAP nie udało się: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Nieudane dodanie użytkownika do {group} grupy:{error}" @@ -6968,43 +6939,43 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 #, fuzzy #| msgid "Failed to add new user to admin group." msgid "Failed to change user status." msgstr "Nieudane dodawanie użytkownika do grupy admin." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Nieudane dodawanie użytkownika do grupy admin: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Utworzono konto użytkownika, możesz się teraz zalogować" @@ -7021,12 +6992,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -7069,17 +7040,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -7110,34 +7081,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7494,7 +7465,7 @@ msgstr "Bezpośrednie połłączenie z internetem." msgid "Server deleted." msgstr "Archiwum zostało usunięte." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7503,7 +7474,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7512,26 +7483,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 #, fuzzy #| msgid "Wiki and Blog" msgid "Website and Blog" @@ -7547,7 +7518,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7560,7 +7531,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7568,11 +7539,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7624,114 +7595,108 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing Backups" -msgid "Error running apt-get" -msgstr "Istniejące kopie zapasowe" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "plik konfiguracyjny: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Instaluj aplikacje" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Błąd podczas instalowania aplikacji: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Błąd podczas instalowania aplikacji: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Błąd podczas instalowania aplikacji: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Błąd podczas instalowania aplikacji: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Aplikacja zainstalowania." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Ostatnie uaktualnienie" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Instaluj aplikacje" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Błąd podczas instalowania aplikacji: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Błąd podczas instalowania aplikacji: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Aplikacja zainstalowania." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7798,56 +7763,56 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "Usługa %(service_name)s nie jest uruchomiona." -#: plinth/templates/base.html:30 -#, fuzzy, python-format -#| msgid "Plinth administrative interface for the %(box_name)s" -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Interfejs administracyjny Plinth dla %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Dom" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Dom" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Aplikacje" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Aplikacje" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Zmień hasło" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Wyłącz" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Wyloguj się" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 #, fuzzy #| msgid "Language" msgid "Select language" msgstr "Język" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Zaloguj się" @@ -8142,6 +8107,40 @@ msgstr "" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Włącz DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Włącz rozszerzenia zabezpieczeń systemu nazw domen" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Proces firewalla nie jest uruchomiony. Proszę go włączyć. Firewall jest " +#~ "domyślnie włączony na %(box_name)s. Na każdym systemie bazującym na " +#~ "Debianie (jak %(box_name)s) możesz go włączyć używając komendy 'service " +#~ "firewalld start' lub, w przypadku systemu z systemd 'systemctl start " +#~ "firewalld'." + +#, fuzzy +#~| msgid "Authentication to remote server failed." +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Nie powiodła się autoryzacja na zdalnym serwerze." + +#, fuzzy +#~| msgid "Existing Backups" +#~ msgid "Error running apt-get" +#~ msgstr "Istniejące kopie zapasowe" + +#, fuzzy, python-format +#~| msgid "Plinth administrative interface for the %(box_name)s" +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Interfejs administracyjny Plinth dla %(box_name)s" + #~ msgid "Access" #~ msgstr "Dostęp" diff --git a/plinth/locale/pt/LC_MESSAGES/django.po b/plinth/locale/pt/LC_MESSAGES/django.po index 0793c57be..60ce22ffd 100644 --- a/plinth/locale/pt/LC_MESSAGES/django.po +++ b/plinth/locale/pt/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Portuguese calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Create new repository" msgid "Name of the new library" msgstr "Criar novo repositório" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1097,22 +1090,22 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "Repository not found" msgid "Library created." msgstr "Repositório não encontrado" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1150,24 +1143,24 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Administração do Servidor" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Configuração Geral" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Configurar" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1274,47 +1267,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Erro ao definir o nome do hospedeiro: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Nome de hospedeiro definido" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Erro ao definir o nome do domínio: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Nome do domínio definido" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Erro ao definir a página inicial do servidor da Web: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Página inicial do servidor da Web definida" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Erro ao alterar o modo avançado: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "A mostrar as aplicações e funcionalidades avançadas" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1322,7 +1315,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1552,11 +1545,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 #, fuzzy #| msgid "Domain Name" msgid "Dynamic Domain Name" @@ -1672,7 +1665,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1737,13 +1730,13 @@ msgstr "" msgid "Already up-to-date" msgstr "Aplicações" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1869,14 +1862,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1884,7 +1877,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1894,13 +1887,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2041,7 +2034,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2049,7 +2042,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -2071,61 +2064,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2171,7 +2155,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2182,85 +2166,85 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid domain name" msgid "Invalid repository URL." msgstr "Nome de domínio inválido" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid domain name" msgid "Invalid repository name." msgstr "Nome de domínio inválido" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 #, fuzzy #| msgid "Repository not found" msgid "Repository's owner name" msgstr "Repositório não encontrado" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create new repository" msgid "Private repository" msgstr "Criar novo repositório" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Create new repository" msgid "Name of the repository" msgstr "Criar novo repositório" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 #, fuzzy #| msgid "Setting unchanged" msgid "Default branch" msgstr "Definição inalterada" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2311,23 +2295,23 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "Apagar este arquivo permanentemente?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 #, fuzzy #| msgid "Repository not found" msgid "Repository created." msgstr "Repositório não encontrado" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 #, fuzzy #| msgid "Repository not found" msgid "Repository edited." msgstr "Repositório não encontrado" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Create new repository" msgid "Edit repository" @@ -2630,7 +2614,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2638,33 +2622,33 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 #, fuzzy #| msgid "Enable application" msgid "Manage I2P application" msgstr "Ativar aplicação" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2709,14 +2693,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2725,15 +2709,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 #, fuzzy #| msgid "Services and Applications" msgid "View and edit wiki applications" @@ -2789,42 +2773,42 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, fuzzy, python-brace-format #| msgid "Archive deleted." msgid "{title} deleted." msgstr "Arquivo apagado." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2832,11 +2816,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2882,7 +2866,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2900,7 +2884,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2910,7 +2894,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2918,15 +2902,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2991,41 +2975,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3035,14 +3019,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3126,7 +3110,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3134,7 +3118,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3143,18 +3127,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3229,49 +3213,49 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 #, fuzzy #| msgid "Applications" msgid "Public registrations enabled" msgstr "Aplicações" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 #, fuzzy #| msgid "Applications" msgid "Public registrations disabled" msgstr "Aplicações" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 #, fuzzy #| msgid "Applications" msgid "Private mode enabled" msgstr "Aplicações" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 #, fuzzy #| msgid "Applications" msgid "Private mode disabled" msgstr "Aplicações" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 #, fuzzy #| msgid "Setting unchanged" msgid "Default skin changed" msgstr "Definição inalterada" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "Nome do domínio definido" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "Nome do domínio definido" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3280,11 +3264,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3331,7 +3315,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3496,19 +3480,19 @@ msgstr "" msgid "Services" msgstr "Descoberta do Serviço" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3858,7 +3842,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3963,7 +3947,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3979,7 +3963,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3992,7 +3976,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4556,7 +4540,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4567,22 +4551,22 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection refused" msgid "Connect to VPN services" msgstr "Conexão recusada" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4592,61 +4576,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4655,33 +4607,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4690,87 +4642,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4804,29 +4756,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4868,8 +4820,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4911,6 +4863,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4942,7 +4925,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4953,7 +4936,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4973,7 +4956,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4983,19 +4966,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5056,7 +5039,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 #, fuzzy #| msgid "Configuration updated" msgid "Access rights configuration updated" @@ -5125,7 +5108,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5138,13 +5121,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5153,31 +5136,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 #, fuzzy #| msgid "Network Time Server" msgid "Network File Storage" @@ -5263,17 +5246,17 @@ msgstr "Nome do arquivo" msgid "Action" msgstr "Aplicações" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "Freedombox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5303,51 +5286,51 @@ msgstr "Aplicações" msgid "Error disabling share: {error_message}" msgstr "Erro a instalar a aplicação: {error}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "Permitir o uso desta aplicação por todos." @@ -5507,14 +5490,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5523,97 +5506,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5650,26 +5633,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5677,14 +5660,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5778,7 +5761,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5826,61 +5809,61 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Repository not found" msgid "manually created" msgstr "Repositório não encontrado" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 #, fuzzy #| msgid "Configuration updated" msgid "Storage snapshots configuration updated" msgstr "Configuração atualizada" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5888,7 +5871,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5923,14 +5906,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5943,7 +5918,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5951,149 +5926,149 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 #, fuzzy #| msgid "Service discovery server is running" msgid "The device is already unmounting." msgstr "O Servidor da descoberta do serviço está a correr" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "Esta operação pode ligar um disco que esteja no estado de adormecido." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid domain name" msgid "Invalid directory name." msgstr "Nome de domínio inválido" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 #, fuzzy #| msgid "Archive name" msgid "Share" msgstr "Nome do arquivo" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6127,7 +6102,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6145,31 +6120,31 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, fuzzy, python-brace-format #| msgid "Error setting language: {exception}" msgid "Error expanding partition: {exception}" msgstr "Erro ao definir a língua: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6177,7 +6152,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6189,20 +6164,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6211,47 +6186,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6353,13 +6328,13 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "General Configuration" msgid "Updating configuration" msgstr "Configuração Geral" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6412,31 +6387,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6444,12 +6419,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6457,8 +6432,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -6466,30 +6441,30 @@ msgstr "" msgid "Software Update" msgstr "Arquivo apagado." -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox Updated" msgstr "Freedombox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 #, fuzzy #| msgid "Applications" msgid "Distribution update started" msgstr "Aplicações" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6651,55 +6626,55 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Aplicações" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 #, fuzzy #| msgid "Applications" msgid "Distribution upgrade disabled" msgstr "Aplicações" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Applications" msgid "Starting distribution upgrade test." msgstr "Aplicações" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6707,15 +6682,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6735,23 +6710,23 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Upload Password" msgid "Invalid password." msgstr "Palavra-passe de Envio" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6760,12 +6735,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6781,41 +6756,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6832,12 +6807,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6875,17 +6850,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6917,34 +6892,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7289,7 +7264,7 @@ msgstr "Erro a estabelecer ligação ao servidor: {}" msgid "Server deleted." msgstr "Arquivo apagado." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7298,7 +7273,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7307,26 +7282,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7340,7 +7315,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7353,7 +7328,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7361,11 +7336,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7415,117 +7390,111 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing Backups" -msgid "Error running apt-get" -msgstr "Backups existentes" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 #, fuzzy #| msgid "Setting unchanged" msgid "media change" msgstr "Definição inalterada" -#: plinth/package.py:395 +#: plinth/package.py:354 #, fuzzy, python-brace-format #| msgid "Configuration" msgid "configuration file: {file}" msgstr "Configuração" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install" msgid "Installing app" msgstr "Instalar" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Erro a instalar a aplicação: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Erro a instalar a aplicação: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Erro a instalar a aplicação: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Erro a instalar a aplicação: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Aplicação instalada." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Name" msgid "App updated" msgstr "Nome" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install" msgid "Uninstalling app" msgstr "Instalar" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Erro a instalar a aplicação: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Erro a instalar a aplicação: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Aplicação instalada." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7577,55 +7546,56 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "O Servidor da descoberta do serviço não está a correr" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 #, fuzzy #| msgid "Language" msgid "Select language" msgstr "Língua" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -7891,6 +7861,17 @@ msgstr "" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Ativar DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Ativar Extensões de segurança do Sistema de Nomes de Domínio" + +#, fuzzy +#~| msgid "Existing Backups" +#~ msgid "Error running apt-get" +#~ msgstr "Backups existentes" + #, fuzzy #~| msgid "Configuration updated" #~ msgid "Tor configuration is being updated" diff --git a/plinth/locale/ru/LC_MESSAGES/django.po b/plinth/locale/ru/LC_MESSAGES/django.po index 7a01812e5..e0a97ccf9 100644 --- a/plinth/locale/ru/LC_MESSAGES/django.po +++ b/plinth/locale/ru/LC_MESSAGES/django.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" -"PO-Revision-Date: 2022-09-14 17:19+0000\n" -"Last-Translator: ikmaak \n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" +"PO-Revision-Date: 2022-10-10 18:05+0000\n" +"Last-Translator: Nikita Epifanov \n" "Language-Team: Russian \n" "Language: ru\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: doc/dev/_templates/layout.html:11 msgid "Page source" @@ -55,17 +55,15 @@ msgstr "Невозможно подключиться к {host}:{port}" #: plinth/forms.py:36 msgid "Backup app before uninstall" -msgstr "" +msgstr "Сделать резервное копирование приложения перед удалением" #: plinth/forms.py:37 msgid "Restoring from the backup will restore app data." -msgstr "" +msgstr "Восстановление из резервной копии восстановит данные приложения." #: plinth/forms.py:39 -#, fuzzy -#| msgid "Repository not found" msgid "Repository to backup to" -msgstr "Репозиторий не найден" +msgstr "Репозиторий для резервного копирования" #: plinth/forms.py:56 msgid "Select a domain name to be used with this application" @@ -118,17 +116,17 @@ msgstr "Веб-сервер" msgid "{box_name} Web Interface (Plinth)" msgstr "{box_name} Веб-интерфейс (Plinth)" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "Доступ к URL {url} по tcp {kind}" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "Доступ к URL {url}" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -145,25 +143,25 @@ msgstr "" "Она может быть отключена в целях повышения безопасности, особенно при " "подключении к вражеской сети." -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "Обнаружение служб" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "Домен локальной сети" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "" "Резервное копирование позволяет создавать и управлять резервными архивами." -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "Резервные копии" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." @@ -172,18 +170,18 @@ msgstr "" "данных. Предпочтительно зашифрованное удаленное место резервного копирования " "или дополнительный подключенный диск." -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "Включить расписание резервного копирования" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "Перейти в {app_name}" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " @@ -193,7 +191,7 @@ msgstr "" "попытки резервного копирования не увенчались успехом. Последняя ошибка: " "{error_message}" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "Ошибка во время резервного копирования" @@ -338,7 +336,7 @@ msgstr "" msgid "Key in Repository" msgstr "Ключ в репозитории" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "нет" @@ -406,7 +404,7 @@ msgstr "Удалённое хранилище резервных копий уж msgid "Select verified SSH public key" msgstr "Выберите проверенный открытый ключ SSH" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." @@ -414,33 +412,33 @@ msgstr "" "В соединении отказано — убедитесь, что вводите правильные учетные данные и " "сервер запущен." -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "В соединении отказано" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "Репозиторий не найден" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "Неправильная парольная фраза шифрования" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "В доступе по SSH отказано" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" "Путь к хранилищу не пустой и не является существующим репозиторием резервных " "копий." -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "Имеющийся репозиторий не зашифрован." -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "Сохранение данных {box_name}" @@ -498,7 +496,7 @@ msgid "Create Location" msgstr "Создание расположения" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "Создать репозиторий" @@ -741,7 +739,7 @@ msgstr "Размонтирование не удалось!" msgid "Mounting failed" msgstr "Монтирование не удалась" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -754,7 +752,7 @@ msgstr "" "просмотреть в браузере. Для общих файлов можно установить срок годности по " "истечении определенного периода времени." -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -766,7 +764,7 @@ msgstr "" "пароль, вы можете поделиться им с пользователями, у которых должны быть " "соответствующие разрешения." -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -777,39 +775,39 @@ msgstr "" "раздать их разным людям или группам. Это позволит вам позже отозвать доступ " "для отдельного человека или группы, удалив их пароль из списка." -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "Прочитать файл, если имеется веб-ссылка на файл" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "Создавать или загружать файлы" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "Список всех файлов и их веб-ссылок" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "Удалить файлы" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "Администрирование файлов: блокировка/разблокировка файлов" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "Нет, пароль требуется всегда" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "Список и чтение всех файлов" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "bepasty" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "Обмен файлами и фрагментами" @@ -823,7 +821,7 @@ msgstr "Разрешения для анонимных пользователе #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "Разрешения" @@ -859,35 +857,35 @@ msgstr "В настоящее время пароли не настроены." #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "Пароль" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "Админ" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "редактор" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "просмотрщик" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "Читать" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "Создать" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "Список" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -899,35 +897,35 @@ msgstr "Список" msgid "Delete" msgstr "Удалить" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "Админ" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "Конфигурация обновлена." -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "Произошла ошибка во время настройки." -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "Пароль добавлен." -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "Добавить пароль" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "Пароль удалён." -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." @@ -935,7 +933,7 @@ msgstr "" "BIND позволяет публиковать информацию о доменных именах (DNS) и разрешать " "DNS запросы устройств в вашей сети." -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -946,32 +944,24 @@ msgstr "" "разрешения запросов DNS для другой машины в локальной сети. Оно также " "несовместимо с общим доступом к подключению интернета от {box_name}." -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "BIND" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "Сервер доменных имен" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "Форвардеры" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" "Список DNS-серверов, разделенных пробелами, которые будут пересылать запросы" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "Включить DNSSEC" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "Включить расширения безопасности системы доменных имен" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "Обслуживание доменов" @@ -1003,19 +993,20 @@ msgstr "IP-адреса" msgid "Refresh IP address and domains" msgstr "Обновите IP-адреса и домены" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "Конфигурация обновлена" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -1026,7 +1017,7 @@ msgstr "" "книг. Вы можете хранить свои электронные книги на {box_name}, читать их в " "Интернете или с любого из своих устройств." -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -1042,7 +1033,7 @@ msgstr "" "последнее прочитанное место, закладки и выделенный текст. Распространение " "контента с использованием OPDS в настоящее время не поддерживается." -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1051,23 +1042,23 @@ msgstr "" "получить доступ к приложению. Все пользователи с доступом могут использовать " "все библиотеки." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Использовать библиотеки электронных книг calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Электронная библиотека" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Название новой библиотеки" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1075,7 +1066,7 @@ msgstr "" "Только буквы английского алфавита и цифры, без пробелов и специальных " "символов. Пример: My_Library_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Библиотека с таким названием уже существует." @@ -1123,20 +1114,20 @@ msgstr "Перейти в библиотеку %(library)s" msgid "Delete library %(library)s" msgstr "Удалить библиотеку %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Библиотека создана." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Ошибка при создании библиотеки." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} удален." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Не удалось удалить {name}: {error}" @@ -1184,7 +1175,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Администрирование сервера" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1192,18 +1183,18 @@ msgstr "" "Здесь вы можете установить такие опции конфигурации, как имя хоста, доменное " "имя, домашняя страница веб-сервера и тому подобное." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Общие настройки" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Настроить" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1297,11 +1288,11 @@ msgstr "" #, fuzzy #| msgid "System Monitoring" msgid "System-wide logging" -msgstr "Системный мониторинг" +msgstr "Общесистемное ведение журнала" #: plinth/modules/config/forms.py:105 msgid "Disable logging, for privacy" -msgstr "" +msgstr "Отключить ведение журнала для обеспечения конфиденциальности" #: plinth/modules/config/forms.py:107 msgid "Keep some in memory until a restart, for performance" @@ -1317,47 +1308,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Ошибка параметра hostname: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Смена имени хоста" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Ошибка параметра имени домена: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Смена доменного имени" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Ошибка параметра домашней страницы веб-сервера: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Установка домашней страницы веб-сервера" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Ошибка при изменении расширенного режима: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Показать продвинутые приложения и функции" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Скрыть продвинутые приложения и функции" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1369,7 +1360,7 @@ msgstr "" "коммуникационные серверы могут использовать его для установления вызова " "между сторонами, которые иначе не могут подключиться друг к другу." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse или ejabberd, должны быть настроены с указанными здесь деталями." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP-помощник" @@ -1443,11 +1434,11 @@ msgstr "Ошибка установки часового пояса: {exception} msgid "Time zone set" msgstr "Смена часового пояса" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge это клиент BitTorrent, имеющий веб-интерфейс." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1455,16 +1446,16 @@ msgstr "" "Пароль по умолчанию - 'deluge', но вы должны войти в систему и изменить его " "сразу после включения этой службы." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Загружать файлы используя приложения BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Delugе" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Веб-клиент BitTorrent" @@ -1592,7 +1583,7 @@ msgstr "Результат" msgid "Diagnostic Test" msgstr "Диагностический тест" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1603,7 +1594,7 @@ msgstr "" "адрес, другим может быть трудно найти вас в Интернете. Это помешает другим " "найти службы, предоставляемые {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1620,7 +1611,7 @@ msgstr "" "сервер будет назначать DNS-имя на новый IP-адрес, и если кто-то из Интернета " "запрашивает DNS-имя, они будут получать ответ ваш текущий IP-адрес." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1633,11 +1624,11 @@ msgstr "" "обновления URL-адреса на freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Клиент динамического DNS" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Динамическое доменное имя" @@ -1765,7 +1756,7 @@ msgstr "Это поле обязательно." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1820,7 +1811,7 @@ msgstr "Сервер отказал в соединении" msgid "Already up-to-date" msgstr "Уже обновлено" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1828,7 +1819,7 @@ msgstr "" "XMPP является открытым и стандартизированным коммуникационным протоколом. " "Здесь вы можете запустить и настроить сервер XMPP, называемый ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client XMPP клиент. Когда включен, ejabberd доступен всем пользователям {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn или настройте внешний сервер." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "еjabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Чат-сервер" @@ -1975,7 +1966,7 @@ msgstr "" "пользователей будет выглядеть как username@%(domainname)s. Вы можете " "настроить ваш домен на странице Настройка." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1985,7 +1976,7 @@ msgstr "" "Postfix отправляет и принимает почту. Dovecot предоставляет доступ почтовым " "клиентам по протоколоам IMAP и POP3. Rspamd фильтрует спам." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1998,7 +1989,7 @@ msgstr "" "электронную почту. Некоторые снимают ограничения после запроса. " "Дополнительную информацию см. на странице руководства." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2014,7 +2005,7 @@ msgstr "" "\", создаются автоматически и переадресуют на адрес администратора, " "созданный первым." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2022,7 +2013,7 @@ msgstr "" "Приложение Roundcube предоставляет " "пользователям веб-интерфейс для доступа к электронной почте." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2153,7 +2144,7 @@ msgstr "Порт" msgid "Host/Target/Value" msgstr "Хост/Цель/Значение" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2165,7 +2156,7 @@ msgstr "" "правильно настроенным, чтобы уменьшить риск информационной опасности из " "Интернета." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Брандмауэр" @@ -2185,53 +2176,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Порт {name} ({details}) недоступен для внешних сетей" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Демон брандмауэра не выполняется. Пожалуйста, запустите его. На %(box_name)s " -"межсетевой экран включен по умолчанию. На любюй системе, базирующейся на " -"Debian (как и %(box_name)s) которые вы можете запустить его с помощью " -"команды 'service firewalld start' или в случае системы с systemd 'systemctl " -"start firewalld'." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Служба/Порт" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Включено" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Выключено" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Разрешено" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Разрешено (только внутренние)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Разрешено (только внешние)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Заблокировано" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2241,13 +2218,13 @@ msgstr "" "разрешается в брандмауэре и при отключении службы она также запрещается в " "брандмауэре." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Дополнительные" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2301,7 +2278,7 @@ msgstr "Начать установку" msgid "Setup Complete" msgstr "Установка Завершена" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2320,7 +2297,7 @@ msgstr "" "нескольких доступных графических клиентов. И вы можете поделиться своим " "кодом с людьми по всему миру." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2328,69 +2305,69 @@ msgstr "" "Чтобы узнать больше о том, как использовать Git, посетите Git tutorial." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Доступ к Git-репозиторию с возможностью чтения и записи" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Простой хостинг Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Неверный URL репозитория." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Неверное имя репозитория." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "Имя нового репозитория или URL для импорта существующего репозитория." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Описание репозитория" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Дополнительно, для показа на Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Имя владельца репозитория" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Частный репозиторий" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" "Доступ к этому репозиторий разрешён только авторизованным пользователям." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Репозиторий с таким именем уже существует." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Имя репозитория" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" "Буквенно-цифровая строка, которая однозначно идентифицирует репозиторий." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Ветка по умолчанию" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb отображает это как ветку по умолчанию." @@ -2434,19 +2411,19 @@ msgstr "Удалить репозиторий Git %(name)s" msgid "Delete this repository permanently?" msgstr "Удалить этот репозиторий навсегда?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Репозиторий создан." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Ошибка при создании репозитория." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Репозиторий отредактирован." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Редактировать репозиторий" @@ -2806,7 +2783,7 @@ msgstr "О {box_name}" msgid "{box_name} Manual" msgstr "Руководство {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2818,7 +2795,7 @@ msgstr "" "обеспечивает анонимность, отправляя зашифрованный трафик через сеть, " "управляемую волонтерами, по всему миру." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2826,26 +2803,26 @@ msgstr "" "Более подробную информацию об I2P можно найти на домашней странице их проекта." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" "При первом посещении веб-интерфейса будет запущен процесс конфигурации." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Управление приложением I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Анонимная сеть" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Прокси" @@ -2890,7 +2867,7 @@ msgstr "" "сети. Скачайте файлы, добавив торренты, или создайте новый торрент, чтобы " "поделиться файлом." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2900,7 +2877,7 @@ msgstr "" "облегченных языков разметки, включая Markdown, и общие функции ведения " "блогов, такие как комментарии и RSS-каналы." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2914,15 +2891,15 @@ msgstr "" "href=\"{users_url}\">Конфигурация пользователей вы можете изменить " "разрешения или добавить новых пользователей." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Вики и Блог" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Просмотр и редактирование приложений Wiki" @@ -2978,41 +2955,41 @@ msgstr "" "Это действие приведет к удалению всех постов, страниц и комментариев, " "включая историю изменений. Окончательно удалить этот вики или блог?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Создать вики {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Не удалось создать вики: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Созданный блог {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Не удалось создать блог: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} удалён." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Не удалось удалить {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted это сервер для Gobby, совместный текстовый редактор." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3023,11 +3000,11 @@ msgstr "" "a>, настольный клиент и установите его. Затем запустите Gobby и выберите " "«Подключиться к серверу» и введите доменное имя вашего {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Сервер Gobby" @@ -3077,7 +3054,7 @@ msgstr "Видеокомната Janus" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Информация о лицензии JavaScript" @@ -3097,7 +3074,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Чат-клиент" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3111,7 +3088,7 @@ msgstr "" "автоматически получать и устанавливать цифровые сертификаты для каждого " "доступного домена." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3124,15 +3101,15 @@ msgstr "" "org/repository/\">Let's Encrypt Subscriber Agreement перед " "использованием этой службы." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Сертификаты" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Невозможно провести тестирование: Не настроены домены." @@ -3197,7 +3174,7 @@ msgstr "" "Домены не настроены. Настройте домены, чтобы " "иметь возможность получать для них сертификаты." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3206,34 +3183,34 @@ msgstr "" "Сертификат успешно отменен для домена {domain}. Для принятия изменений может " "потребоваться время." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Не удалось отозвать сертификат для домена {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Сертификат успешно получен для домена {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Не удалось получить сертификат для домена {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Сертификат успешно удален для домена {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Не удалось удалить сертификат для домена {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3250,7 +3227,7 @@ msgstr "" "одном сервере Matrix могут общаться с пользователями на всех остальных " "серверах." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3260,7 +3237,7 @@ msgstr "" "Установите приложение Coturn или настройте " "внешний сервер." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3369,7 +3346,7 @@ msgstr "" "Пожалуйста, посетите Let's Encrypt, " "чтобы получить его." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3381,7 +3358,7 @@ msgstr "" "редактируемого сайта. Вы можете использовать mediawiki как сайт, делать " "заметки или работать совместно с друзьями." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3396,7 +3373,7 @@ msgstr "" "перейдя в раздел Special:CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3404,12 +3381,12 @@ msgstr "" "Кто угодно, имея ссылку на wiki, может читать её. Только зарегистрированные " "пользователи могут вносить изменения." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3492,35 +3469,35 @@ msgstr "Пароль обновлен" msgid "Password update failed. Please choose a stronger password" msgstr "Не удалось обновить пароль. Пожалуйста, выберите более надежный пароль" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Публичная регистрация включена" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Публичная регистрация отключена" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Режим приватности включен" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Режим приватности выключен" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Скин по умолчанию изменен" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Доменное имя обновлено" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Название сайта обновлено" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3533,11 +3510,11 @@ msgstr "" "умолчанию (30000). Для подключения к серверу необходим клиент Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Песочница" @@ -3589,7 +3566,7 @@ msgstr "" msgid "Address" msgstr "Адрес" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3775,7 +3752,7 @@ msgstr "Sеcure Shell" msgid "Services" msgstr "Службы" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3783,7 +3760,7 @@ msgstr "" "Настроить сетевые устройства. Подключайтесь к Интернету через Ethernet, Wi-" "Fi или PPPoE. Поделитесь этим подключением с другими устройствами в сети." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3791,7 +3768,7 @@ msgstr "" "Устройства, администрируемые другими методами, могут быть недоступны для " "настройки здесь." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Сети" @@ -4226,7 +4203,7 @@ msgstr "Редактирование подключения" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Редактировать" @@ -4331,7 +4308,7 @@ msgstr "IРv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Метод" @@ -4347,7 +4324,7 @@ msgstr "DNS-сервер" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "По умолчанию" @@ -4360,7 +4337,7 @@ msgid "This connection is not active." msgstr "Это подключение не активно." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Безопасность" @@ -4946,7 +4923,7 @@ msgstr "Подключение {name} удалено." msgid "Failed to delete connection: Connection not found." msgstr "Не удалось удалить подключение: соединение не найдено." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4964,20 +4941,20 @@ msgstr "" "также получить доступ к остальной части Интернет через {box_name} для " "дополнительной безопасности и анонимности." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Подключение к службам VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Виртуальная частная сеть" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4988,58 +4965,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Миграция на ECC" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Ваша установка OpenVPN в настоящее время использует RSA. Переход на " -"современную криптографию Elliptic Curve Cryptography повышает скорость " -"установления соединения и безопасность. Эта операция необратима. Она должна " -"занять всего несколько минут на большинстве одноплатных компьютеров." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Все новые установки OpenVPN на %(box_name)s будут использовать ECC по " -"умолчанию. Мы рекомендуем выполнить миграцию как можно скорее." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Предупреждение: Существующие профили клиентов будут аннулированы этой " -"операцией. Все пользователи OpenVPN на %(box_name)s должны загрузить свои " -"новые профили. Для подключения к этому серверу следует использовать клиенты " -"OpenVPN, совместимые с ECC." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Мигрировать" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Профиль" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Чтобы подключиться к VPN %(box_name)s, вам необходимо загрузить профиль и " @@ -5048,18 +4988,19 @@ msgstr "" "\" выше, чтобы просмотреть рекомендуемые клиенты и инструкции по их " "настройке." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Профиль специфичен для каждого пользователя %(box_name)s. Держите профиль в " "тайне." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Скачать мой профиль" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5072,19 +5013,19 @@ msgstr "" "недоступны из остальной части интернета. Это включает в себя следующие " "ситуации:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} ограничен брандмауэром." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} подключен к маршрутизатору (беспроводному), который вы не " "контролируете." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5092,7 +5033,7 @@ msgstr "" "Ваш провайдер не предоставляет вам внешний IP-адрес и вместо этого " "обеспечивает подключение к Интернету через NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5100,11 +5041,11 @@ msgstr "" "Ваш провайдер не предоставляет вам статический IP-адрес, и ваш-IP адрес " "изменяется каждый раз при подключении к Интернету." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Ваш провайдер ограничивает входящие соединения." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5117,23 +5058,23 @@ msgstr "" "услуг pagekite, например pagekite.net. " "В будущем, для этого возможно будет использовать {box_name} вашего приятеля." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PаgeKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Публичная видимость" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite Домен" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Домен сервера" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5141,31 +5082,31 @@ msgstr "" "Выберите свой сервер pagekite. Выберите \"pagekite.net\", чтобы использовать " "сервер по умолчанию - pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Порт сервера" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Порт сервера pagekite (по умолчанию: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Имя Kite" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Пример: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Недопустимое имя kite" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite secrеt" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5173,35 +5114,35 @@ msgstr "" "Секрет, связанный с kite или секрет по умолчанию для вашей учетной записи, " "если не секрет устанавливается на kite." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "протокол" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "внешний (frontend) порт" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "Внутренний (freedombox) порт" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Включить поддомены" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Удалить пользовательские службы" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Эта служба уже доступна как стандартная." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Добавить пользовательскую службу" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Эта служба уже существует" @@ -5238,29 +5179,29 @@ msgstr "" "все комбинации протокол/порт, которые вы можете здесь задать. Например, " "HTTPS на портах, отличных от 443, может вызывать проблемы." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Веб-сервер (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Сайт будет доступен на http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Веб-сервер (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Сайт будет доступен на https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Sеcure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5312,8 +5253,8 @@ msgstr "" "Другая установка или обновление уже запущенны. Пожалуйста, подождите " "несколько минут перед выключением или перезагрузкой." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Перезапустить" @@ -5363,6 +5304,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Завершить работу сейчас" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5409,7 +5383,7 @@ msgstr "Web-прокси" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Доступ к {url} с прокси {proxy} на tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5426,7 +5400,7 @@ msgstr "" "клиентов. Для этого могут использоваться как клиенты настольного компьютера, " "так и мобильные версии." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your для десктопов и мобильных устройств." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC-клиент" @@ -5450,7 +5424,7 @@ msgstr "IRC-клиент" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5465,7 +5439,7 @@ msgstr "" "supported-clients\">поддерживаемое клиентское приложение. Доступ к " "Radicale может получить любой пользователь с логином {box_name}." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5475,12 +5449,12 @@ msgstr "" "создание новых календарей и адресных книг. Он не поддерживает добавление " "событий или контактов, для этого требуется отдельный клиент." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Календарь и Адресная книга" @@ -5554,7 +5528,7 @@ msgstr "" "address>) и ваше имя пользователя. Нажав на кнопку поиска будет список " "существующих календарей и адресных книг." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Конфигурация прав доступа обновлена" @@ -5644,7 +5618,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Чтение и подписка на ленты новостей" @@ -5659,7 +5633,7 @@ msgstr "Мост" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5667,7 +5641,7 @@ msgstr "" "Samba позволяет обмениваться файлами и папками между FreedomBox и другими " "компьютерами в вашей локальной сети." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5680,11 +5654,11 @@ msgstr "" "вашем компьютере по адресу \\\\{hostname} (в Windows) или smb://{hostname}." "local (в Linux и Mac). Вы можете выбрать один из трёх типов: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Открытый общий ресурс - доступен всем в вашей локальной сети." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5692,7 +5666,7 @@ msgstr "" "Общий доступ к группе - доступен только пользователям FreedomBox, которые " "находятся в группе Freedombox-share." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5700,15 +5674,15 @@ msgstr "" "Домашняя папка - каждый пользователь в группе Freedombox-share может иметь " "собственное личное пространство." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Доступ к частным общим ресурсам" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Сетевое хранилище файлов" @@ -5797,15 +5771,15 @@ msgstr "Имя общего ресурса" msgid "Action" msgstr "Действие" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "Диск ОС FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Открытый ресурс" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Групповой ресурс" @@ -5831,7 +5805,7 @@ msgstr "Общий доступ отключён." msgid "Error disabling share: {error_message}" msgstr "Ошибка отключения общего доступа: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5839,7 +5813,7 @@ msgstr "" "Searx - это конфиденциальная метапоисковая система. Она агрегирует и " "показывает результаты с разных поисковых систем." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5847,41 +5821,41 @@ msgstr "" "Searx может быть использован, чтобы избежать отслеживания и профилирования " "поисковыми системами. Она не хранит никаких файлов cookie по умолчанию." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Поиск в интернете" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Веб-поиск" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Безопасный Поиск" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Выберите семейный фильтр по умолчанию, чтобы применить к вашим результатам " "поиска." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Умеренный" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Строгий" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Разрешить публичный доступ" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "Разрешите использовать это приложение всем, у кого есть доступ к нему." @@ -6062,7 +6036,7 @@ msgstr "Закладки" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6072,7 +6046,7 @@ msgstr "" "защиты вашего интернет-трафика. Его можно использовать для обхода интернет-" "фильтрации и цензуры." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6085,7 +6059,7 @@ msgstr "" "SOCKS5. Локальные устройства могут подключаться к этому прокси, и их данные " "будут шифроваться и передаваться через сервер Shadowsocks." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6094,42 +6068,42 @@ msgstr "" "в вашем устройстве, браузере или приложении на http://" "freedombox_address:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Прокси Socks5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Рекомендуется" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Сервер" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Имя или IP адрес сервера" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Номер порта сервера" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Пароль, используемый для шифрования данных. Должен совпадать с паролем " "сервера." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Метод шифрования. Должен соответствовать параметру на сервере." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6138,15 +6112,15 @@ msgstr "" "Общий доступ позволяет обмениваться файлами и папками на вашем {box_name} " "через сеть с выбранными группами пользователей." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Общий доступ" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Имя общего ресурса" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6154,37 +6128,37 @@ msgstr "" "Цифро-буквенная строка в нижнем регистре, однозначно идентифицирующая " "ресурс. Пример: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Путь к общему ресурсу" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Путь к папке на диске этого сервера, которую вы хотите сделать общей." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Публичный доступ" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Сделайте файлы в этой папке доступными для всех, у кого есть ссылка." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Группы пользователей, которые могут читать файлы в общей папке:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "Пользователи выбранных групп смогут читать файлы в общей папке." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Общий ресурс с таким именем уже существует." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" "Общий доступ должны быть публично доступным или доступными хотя бы для одной " @@ -6223,19 +6197,19 @@ msgstr "Общий ресурс добавлен." msgid "Add Share" msgstr "Добавить общий ресурс" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Общий ресурс изменён." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Редактировать общий ресурс" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Общий ресурс удалён." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6245,7 +6219,7 @@ msgstr "" "btrfs. Они могут использоваться для отката системы к последнему рабочему " "состоянию в случае неприемлемых изменений в системе." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6256,7 +6230,7 @@ msgstr "" "до и после инсталляции программного обеспечения. Старые снимки автоматически " "удаляются в соответствии с установками ниже." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups, так как они хранятся на том же разделе. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Хранилище снимков" @@ -6370,7 +6344,7 @@ msgstr "Дата" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Удалить снапшот" @@ -6422,57 +6396,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Откат к снимку %(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "создано вручную" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "временная шкала" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Управление снапшотами" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Создан снимок." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Настройки хранения снапшотов обновлены" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Ошибка действий: {0}[{1}][{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Удалить выбранные снапшоты" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Снимок сейчас используется. Попробуйте позже." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Откат к снимку #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Необходимо перезагрузить систему для завершения отката." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Откат к снимку" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6484,7 +6458,7 @@ msgstr "" "может выполнять задачи администрирования, копировать файлы или запускать " "другие службы с использованием таких соединений." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Secure Shell (SSH) сервер" @@ -6522,14 +6496,6 @@ msgstr "Алгоритм" msgid "Fingerprint" msgstr "Отпечаток" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "SSH-аутентификация с отключенным паролем." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "SSH-аутентификация с включённым паролем." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Единый вход" @@ -6542,7 +6508,7 @@ msgstr "Логин" msgid "Logged out successfully." msgstr "Выход выполнен успешно." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6553,107 +6519,107 @@ msgstr "" "{box_name}. Вы можете видеть, какие носители используются, монтировать и " "размонтировать подключаемые носители, увеличивать корневой раздел итп." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Хранилище" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} байт" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} КиБ" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} Миб" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} Гиб" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} Тиб" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Операция не удалась." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Операция была отменена." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Устройство уже отключается." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "Операция не поддерживается из-за отсутствия поддержки драйвера или утилиты." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Время операции вышло." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "Операция пробудит диск, находящийся в режиме глубокого сна." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Попытка отключения устройства, которое используется." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Операция уже отменена." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Отсутствует авторизация для выполнения запрошенной операции." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Устройство уже подключено." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Устройство не подключено." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Использование запрошенной опции не разрешено." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Устройство подключено другим пользователем." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Недостаточно места в системном разделе: использовано {percent_used}%, " "свободно {free_space}." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Недостаточно места на диске" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Неизбежный сбой диска" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6662,39 +6628,39 @@ msgstr "" "Диск {id} сообщает, что в ближайшем будущем он может выйти из строя. " "Скопируйте любые данные, пока еще можете, и замените диск." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Неверное имя каталога." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Каталог не существует." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Путь не каталог." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Каталог не читается пользователем." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Каталог не доступен для записи пользователем." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Каталог" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Подкаталог (необязательно)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Поделиться" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Другой каталог (укажите ниже)" @@ -6732,7 +6698,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Расширить корневой раздел" @@ -6756,30 +6722,30 @@ msgstr "" "этой операции будет доступно %(expandable_root_size)s свободного места в " "вашем корневом разделе." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Ошибка расширения раздела: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Раздел успешно расширен." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor}{drive_model} может быть безопасно отсоединено." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Устройство может быть безопасно отсоединено." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Ошибка извлечения устройства: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6791,7 +6757,7 @@ msgstr "" "или удаление файлов на одном устройстве будет автоматически реплицироваться " "на все другие устройства, на которых работает Syncthing." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6810,20 +6776,20 @@ msgstr "" "собственный набор папок. Веб-интерфейс доступен только для пользователей, " "принадлежащих к группе «admin» или «syncthing-access»." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Администрирование приложения Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Синхронизация файлов" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6837,7 +6803,7 @@ msgstr "" "\"https://www.torproject.org/download/download-easy.html.en\">Tor Browser." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6845,40 +6811,40 @@ msgid "" msgstr "" "Порт Tor SOCKS доступен на {box_name} для внутренних сетей на TCP-порту 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Сервис Tor Onion" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor Socks прокси" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Ретранслятор Tor типа мост" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Доступен порт трансляции Tor" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 транспорт зарегестрирован" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 транспорт зарегистрирован" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Доступ к {url} по tcp{kind} через Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Подтверждение использования Tor в {url} по tcp {kind}" @@ -6997,13 +6963,13 @@ msgstr "Onion сервис" msgid "Ports" msgstr "Порты" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Произошла ошибка во время настройки." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -7066,7 +7032,7 @@ msgstr "" msgid "Transmission" msgstr "Transmissiоn" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7075,7 +7041,7 @@ msgstr "" "Tiny Tiny RSS это новый (RSS/Atom) агрегатор новостей, позволяющий читать " "новости из любого места, так же удобно, как и в настольных приложениях." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7084,7 +7050,7 @@ msgstr "" "Когда Tiny Tiny RSS включен, доступ к нему может получить любой пользователь, принадлежащий к группе feed-reader." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7093,11 +7059,11 @@ msgstr "" "Tiny RSS используйте URL / tt-rss-app для " "подключения." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Чтение ленты новостей" @@ -7105,12 +7071,12 @@ msgstr "Чтение ленты новостей" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "Проверьте и установите новейшие программы и обновления безопасности." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7124,22 +7090,22 @@ msgstr "" "выполняется автоматически в 02:00, в результате чего все приложения на " "короткое время становятся недоступными." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Обновление программного обеспечения" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox обновлён" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Не удалось запустить обновление дистрибутива" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7149,11 +7115,11 @@ msgstr "" "дистрибутива. Пожалуйста, убедитесь, что свободно не менее 5 ГБ. Обновление " "дистрибутива будет повторно запущено через 24 часа, если это включено." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Началось обновление дистрибутива" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7332,46 +7298,46 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Обновление дистрибутива включено" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Ошибка при настройке автоматического обновления: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Автоматические обновления включены" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Автоматические обновления отключены" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Обновление дистрибутива включено" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Обновление дистрибутива отключено" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Начался процесс обновления." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Не удалось запустить обновление." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Активированы частые обновления функций." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Distribution upgrade enabled" msgid "Starting distribution upgrade test." msgstr "Обновление дистрибутива включено" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7383,7 +7349,7 @@ msgstr "" "запись пользователя была частью группы, чтобы разрешить пользователю доступ " "к приложению." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7395,15 +7361,15 @@ msgstr "" "пользователи группы admin могут изменять приложения или системные " "настройки." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Пользователи и группы" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Доступ ко всем сервисам и настройкам системы" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Проверьте запись LDAP \"{search_item}\"" @@ -7422,11 +7388,11 @@ msgid "" msgstr "" "Требуется. 150 символов или меньше. Только английские буквы, цифры и @/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Пароль авторизации" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7434,11 +7400,11 @@ msgstr "" "Введите пароль пользователя \"{user}\" для авторизации изменений учетной " "записи." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Неправильный пароль." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7452,12 +7418,12 @@ msgstr "" "\" смогут войти во все службы. Они также могут входить в систему через SSH и " "иметь привилегии администратора (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Не удалось создать пользователя LDAP: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Не удалось добавить нового пользователя в группу {group}: {error}" @@ -7477,42 +7443,42 @@ msgstr "" "на каждой строке. Пустые строки и строки, начинающиеся с # будут " "игнорироваться." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Переименование пользователя LDAP не удалось." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Не удалось удалить пользователя из группы." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Не удалось добавить пользователя в группу." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Не удалось задать ключи SSH." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Не удалось изменить статус пользователя." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Изменение LDAP пароля пользователя не удалось." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" "Не удалось добавить нового пользователя в группу администраторов: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Не удалось ограничить доступ к консоли: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Учетная запись пользователя создана, теперь вы вошли" @@ -7529,12 +7495,12 @@ msgstr "Сохранить пароль" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Создать пользователя" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Удаление пользователя" @@ -7575,13 +7541,19 @@ msgid "The following administrator accounts exist in the system." msgstr "В системе существуют следующие учетные записи администратора." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Удалите эти учетные записи из командной строки и обновите страницу, чтобы " "создать учетную запись, которую можно использовать с %(box_name)s. В " @@ -7590,7 +7562,7 @@ msgstr "" "с %(box_name)s, пропустите этот шаг." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Пользователи" @@ -7623,34 +7595,34 @@ msgstr "" msgid "Save Changes" msgstr "Сохранить изменения" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Пользователь %(username)s создан." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Пользователь %(username)s обновлен." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Редактирование пользователя" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Пользователь {user} удален." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Сбой при удалении LDAP пользователя." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Изменить пароль" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Пароль успешно изменён." @@ -7987,7 +7959,7 @@ msgstr "Удалить соединение с сервером" msgid "Server deleted." msgstr "Сервер удален." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8001,7 +7973,7 @@ msgstr "" "помощью тем. Интерфейс администрирования и созданные веб-страницы подходят " "для мобильных устройств." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8015,7 +7987,7 @@ msgstr "" "ссылки в интерфейсе администратора для улучшения URL-адресов ваших страниц и " "сообщений." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8026,7 +7998,7 @@ msgstr "" "закладку на страницу администратора, " "чтобы в будущем иметь доступ к интерфейсу администрирования." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8036,12 +8008,12 @@ msgstr "" "базы данных из интерфейса администратора. Дополнительные плагины или темы " "могут быть установлены и обновлены на ваш страх и риск." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Сайт и блог" @@ -8058,7 +8030,7 @@ msgstr "" "просматривать сайт или блог WordPress. Включайте только после первоначальной " "настройки WordPress." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8081,7 +8053,7 @@ msgstr "" "месте. Отдельными фотографиями можно поделиться с другими, отправив прямую " "ссылку." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8092,11 +8064,11 @@ msgstr "" "Zoph. Для дополнительных пользователей необходимо создать учетные записи как " "в {box_name}, так и в Zoph с тем же именем пользователя." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Организатор фотографий" @@ -8151,116 +8123,110 @@ msgstr "" msgid "Finished: {name}" msgstr "Служба выключена: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Пакет {expression} недоступен для установки" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Пакет {package_name} последней версией ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Ошибка во время резервного копирования" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "Установка" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "Загрузка" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "изменение медиа" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "Файл настроек: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "Установка приложений" -#: plinth/setup.py:42 +#: plinth/setup.py:43 #, fuzzy #| msgid "Updating..." msgid "Updating app" msgstr "Обновляется..." -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Ошибка при установке пакетов: {string}{details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Ошибка при установке пакетов: {string}{details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Ошибка при установке приложения: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Ошибка при установке приложения: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Приложение установлено." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "Последнее обновление" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "Установка приложений" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Ошибка при установке пакетов: {string}{details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Ошибка при установке приложения: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Приложение установлено." -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8322,53 +8288,54 @@ msgstr "Установка" msgid "Service %(service_name)s is not running." msgstr "Служба %(service_name)s не запущена." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Базовая функциональность и веб-интерфейс %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Домой" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Домой" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Приложения" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Приложения" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Система" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Система" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Изменить пароль" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Завершить работу" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Выход" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Выберите язык" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Войти" @@ -8659,6 +8626,78 @@ msgstr "" msgid "Gujarati" msgstr "Гуджарати" +#~ msgid "Enable DNSSEC" +#~ msgstr "Включить DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Включить расширения безопасности системы доменных имен" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Демон брандмауэра не выполняется. Пожалуйста, запустите его. На " +#~ "%(box_name)s межсетевой экран включен по умолчанию. На любюй системе, " +#~ "базирующейся на Debian (как и %(box_name)s) которые вы можете запустить " +#~ "его с помощью команды 'service firewalld start' или в случае системы с " +#~ "systemd 'systemctl start firewalld'." + +#~ msgid "Migrate to ECC" +#~ msgstr "Миграция на ECC" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Ваша установка OpenVPN в настоящее время использует RSA. Переход на " +#~ "современную криптографию Elliptic Curve Cryptography повышает скорость " +#~ "установления соединения и безопасность. Эта операция необратима. Она " +#~ "должна занять всего несколько минут на большинстве одноплатных " +#~ "компьютеров." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Все новые установки OpenVPN на %(box_name)s будут использовать ECC по " +#~ "умолчанию. Мы рекомендуем выполнить миграцию как можно скорее." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Предупреждение: Существующие профили клиентов будут аннулированы " +#~ "этой операцией. Все пользователи OpenVPN на %(box_name)s должны загрузить " +#~ "свои новые профили. Для подключения к этому серверу следует использовать " +#~ "клиенты OpenVPN, совместимые с ECC." + +#~ msgid "Migrate" +#~ msgstr "Мигрировать" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "SSH-аутентификация с отключенным паролем." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "SSH-аутентификация с включённым паролем." + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Ошибка во время резервного копирования" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Базовая функциональность и веб-интерфейс %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Сетевые подключения" diff --git a/plinth/locale/si/LC_MESSAGES/django.po b/plinth/locale/si/LC_MESSAGES/django.po index d4efbfaab..9d2098172 100644 --- a/plinth/locale/si/LC_MESSAGES/django.po +++ b/plinth/locale/si/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-04-27 13:32+0000\n" "Last-Translator: HelaBasa \n" "Language-Team: Sinhala calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1021,20 +1014,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1072,24 +1065,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1185,47 +1178,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1233,7 +1226,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1463,11 +1456,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1579,7 +1572,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1634,13 +1627,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1762,14 +1755,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1777,7 +1770,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1787,13 +1780,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1918,7 +1911,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1926,7 +1919,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1946,61 +1939,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2046,7 +2030,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2057,73 +2041,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2167,19 +2151,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2472,7 +2456,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2480,31 +2464,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2541,14 +2525,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2557,15 +2541,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2619,41 +2603,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2661,11 +2645,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2711,7 +2695,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2729,7 +2713,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2739,7 +2723,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2747,15 +2731,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2818,41 +2802,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2862,14 +2846,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2950,7 +2934,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2958,7 +2942,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2967,18 +2951,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3047,35 +3031,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3084,11 +3068,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3133,7 +3117,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3292,19 +3276,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3650,7 +3634,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3755,7 +3739,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3771,7 +3755,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3784,7 +3768,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4320,7 +4304,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4331,20 +4315,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4354,61 +4338,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4417,33 +4369,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4452,87 +4404,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4566,29 +4518,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4630,8 +4582,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4673,6 +4625,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4704,7 +4687,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4715,7 +4698,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4735,7 +4718,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4745,19 +4728,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4816,7 +4799,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4883,7 +4866,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4896,13 +4879,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4911,31 +4894,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5013,15 +4996,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5047,51 +5030,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5244,14 +5227,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5260,97 +5243,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5387,26 +5370,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5414,14 +5397,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5515,7 +5498,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5563,57 +5546,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5621,7 +5604,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5654,14 +5637,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5674,7 +5649,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5682,143 +5657,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5852,7 +5827,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5870,30 +5845,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5901,7 +5876,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5913,20 +5888,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5935,47 +5910,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6073,11 +6048,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6129,31 +6104,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6161,12 +6136,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6174,33 +6149,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6348,51 +6323,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6400,15 +6375,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6426,21 +6401,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6449,12 +6424,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6470,41 +6445,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6521,12 +6496,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6564,17 +6539,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6605,34 +6580,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6941,7 +6916,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6950,7 +6925,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6959,26 +6934,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6992,7 +6967,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7005,7 +6980,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7013,11 +6988,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7066,96 +7041,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7206,53 +7177,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/sl/LC_MESSAGES/django.po b/plinth/locale/sl/LC_MESSAGES/django.po index fae756c6e..3b13f5716 100644 --- a/plinth/locale/sl/LC_MESSAGES/django.po +++ b/plinth/locale/sl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Slovenian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 #, fuzzy #| msgid "Create new repository" msgid "Name of the new library" msgstr "Ustvari novo skladišče" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 #, fuzzy #| msgid "Create remote backup repository" msgid "A library with this name already exists." @@ -1146,22 +1139,22 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "Repository not found" msgid "Library created." msgstr "Ne najdem skladišča" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1211,24 +1204,24 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Skrbništvo strežnika" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Nastavitve" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1334,47 +1327,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1382,7 +1375,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1615,11 +1608,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 #, fuzzy #| msgid "Domain Name" msgid "Dynamic Domain Name" @@ -1733,7 +1726,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1790,13 +1783,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1920,14 +1913,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1935,7 +1928,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1945,13 +1938,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2090,7 +2083,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2098,7 +2091,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -2118,61 +2111,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2218,7 +2202,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2229,85 +2213,85 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository URL." msgstr "Neveljavno ime gostitelja" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid repository name." msgstr "Neveljavno ime gostitelja" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 #, fuzzy #| msgid "Repository not found" msgid "Repository's owner name" msgstr "Ne najdem skladišča" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 #, fuzzy #| msgid "Create new repository" msgid "Private repository" msgstr "Ustvari novo skladišče" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 #, fuzzy #| msgid "Create remote backup repository" msgid "A repository with this name already exists." msgstr "Ustvari oddaljeno skladišče za rezervne kopije" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 #, fuzzy #| msgid "Create new repository" msgid "Name of the repository" msgstr "Ustvari novo skladišče" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2358,23 +2342,23 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "Želite ta arhiv trajno izbrisati?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 #, fuzzy #| msgid "Repository not found" msgid "Repository created." msgstr "Ne najdem skladišča" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 #, fuzzy #| msgid "Repository not found" msgid "Repository edited." msgstr "Ne najdem skladišča" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 #, fuzzy #| msgid "Create new repository" msgid "Edit repository" @@ -2669,7 +2653,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2677,31 +2661,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2738,14 +2722,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2754,15 +2738,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2816,42 +2800,42 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, fuzzy, python-brace-format #| msgid "Archive deleted." msgid "{title} deleted." msgstr "Arhiv je izbrisan." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2859,11 +2843,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2909,7 +2893,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2927,7 +2911,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2937,7 +2921,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2945,15 +2929,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3016,41 +3000,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3060,14 +3044,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3148,7 +3132,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3156,7 +3140,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3165,18 +3149,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3247,39 +3231,39 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain Name" msgid "Domain name updated" msgstr "Ime domene" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain Name" msgid "Site name updated" msgstr "Ime domene" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3288,11 +3272,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3337,7 +3321,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3500,19 +3484,19 @@ msgstr "" msgid "Services" msgstr "Odkrivanje storitev" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3858,7 +3842,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3963,7 +3947,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3979,7 +3963,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3992,7 +3976,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4540,7 +4524,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4551,22 +4535,22 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 #, fuzzy #| msgid "Connection refused" msgid "Connect to VPN services" msgstr "Povezava je zavrnjena" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4576,61 +4560,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4639,33 +4591,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4674,87 +4626,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4788,29 +4740,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4852,8 +4804,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4895,6 +4847,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4926,7 +4909,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4937,7 +4920,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4957,7 +4940,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4967,19 +4950,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5038,7 +5021,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -5113,7 +5096,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5126,13 +5109,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5141,31 +5124,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5245,17 +5228,17 @@ msgstr "" msgid "Action" msgstr "Šifriranje" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5283,51 +5266,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "Napaka ob nameščanju aplikacije: {error}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5482,14 +5465,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5498,97 +5481,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5625,26 +5608,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5652,14 +5635,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5753,7 +5736,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5801,59 +5784,59 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Repository not found" msgid "manually created" msgstr "Ne najdem skladišča" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5861,7 +5844,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5896,14 +5879,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5916,7 +5891,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5924,145 +5899,145 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid directory name." msgstr "Neveljavno ime gostitelja" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6096,7 +6071,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6114,30 +6089,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6145,7 +6120,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6157,20 +6132,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6179,47 +6154,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6317,13 +6292,13 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "Configuration updated" msgid "Updating configuration" msgstr "Konfiguracija je posodobljena" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6384,14 +6359,14 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Cockpit will be available from /" @@ -6406,17 +6381,17 @@ msgstr "" "\"{users_url}\">katerikoli uporabnik na {box_name}, ki je član skupine " "skrbnikov." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6424,12 +6399,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6437,8 +6412,8 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 #, fuzzy @@ -6446,28 +6421,28 @@ msgstr "" msgid "Software Update" msgstr "Arhiv je izbrisan." -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox Updated" msgstr "FreedomBox" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6617,51 +6592,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6669,15 +6644,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6697,23 +6672,23 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 #, fuzzy #| msgid "Invalid hostname" msgid "Invalid password." msgstr "Neveljavno ime gostitelja" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6722,12 +6697,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6743,41 +6718,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6794,12 +6769,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6837,17 +6812,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6878,34 +6853,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7246,7 +7221,7 @@ msgstr "Napaka ob nameščanju aplikacije: {error}" msgid "Server deleted." msgstr "Arhiv je izbrisan." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7255,7 +7230,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7264,26 +7239,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7297,7 +7272,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7310,7 +7285,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7318,11 +7293,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7372,112 +7347,106 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing backups" -msgid "Error running apt-get" -msgstr "Obstoječe rezervne kopije" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Napaka ob nameščanju aplikacije: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Napaka ob nameščanju aplikacije: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Napaka ob nameščanju aplikacije: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Napaka ob nameščanju aplikacije: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Aplikacija je nameščena." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Name" msgid "App updated" msgstr "Ime" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "Napaka ob nameščanju aplikacije: {error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Napaka ob nameščanju aplikacije: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Napaka ob nameščanju aplikacije: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Aplikacija je nameščena." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7528,53 +7497,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Aplikacije" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -7839,6 +7809,17 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "Omogoči DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Omogoči varnostne razširitve DNSSEC" + +#, fuzzy +#~| msgid "Existing backups" +#~ msgid "Error running apt-get" +#~ msgstr "Obstoječe rezervne kopije" + #, fuzzy #~| msgid "Archive deleted." #~ msgid "Server URL updated" diff --git a/plinth/locale/sq/LC_MESSAGES/django.po b/plinth/locale/sq/LC_MESSAGES/django.po index 933386cdd..e67a2e54a 100644 --- a/plinth/locale/sq/LC_MESSAGES/django.po +++ b/plinth/locale/sq/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" -"PO-Revision-Date: 2022-09-14 17:20+0000\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" +"PO-Revision-Date: 2022-10-10 13:34+0000\n" "Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1-dev\n" +"X-Generator: Weblate 4.14.1\n" #: doc/dev/_templates/layout.html:11 msgid "Page source" @@ -54,11 +54,11 @@ msgstr "S’lidhet dot me {host}:{port}" #: plinth/forms.py:36 msgid "Backup app before uninstall" -msgstr "" +msgstr "Kopjeruani aplikacionin, para se të çinstalohet" #: plinth/forms.py:37 msgid "Restoring from the backup will restore app data." -msgstr "" +msgstr "Rikthimi prej kopjeruajtjes do të rikthejë të dhëna aplikacioni." #: plinth/forms.py:39 msgid "Repository to backup to" @@ -115,17 +115,17 @@ msgstr "Shërbyes" msgid "{box_name} Web Interface (Plinth)" msgstr "Ndërfaqe Web e {box_name} (Plinth)" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "URL hyrjeje {url} në tcp{kind}" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "URL Hyrjeje {url}" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -142,24 +142,24 @@ msgstr "" "në rrjete të brendshëm. Mund të çaktivizohet, për të përmirësuar sigurinë, " "veçanërisht kur bëhet lidhje te një rrjet vendor jomikpritës." -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "Zbulim Shërbimesh" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "Përkatësi Rrjeti Vendor" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "Kopjeruajtjet lejojnë krijim dhe administrim arkivash kopjeruajtjeje." -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "Kopjeruajtje" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." @@ -168,18 +168,18 @@ msgstr "" "Parapëlqeni një vendndodhje të largët kopjeruajtjesh të fshehtëzuara ose një " "disk ekstra bashkëngjitur." -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "Aktivizoni një Plan Kopjeruajtjesh" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "Kalo te {app_name}" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " @@ -188,7 +188,7 @@ msgstr "" "Dështoi një kopjeruajtje e planifikuar. {error_count} përpjekjet e mëparshme " "nuk patën sukses. Gabimi i fundit qe: {error_message}" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "Gabim Gjatë Kopjeruajtjes" @@ -333,7 +333,7 @@ msgstr "" msgid "Key in Repository" msgstr "Kyç në Depo" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "Asnjë" @@ -401,7 +401,7 @@ msgstr "Depoja e largët e kopjeruajtjeve ekziston tashmë." msgid "Select verified SSH public key" msgstr "Përzgjidhni kyç SSH publik të verifikuar" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." @@ -409,33 +409,33 @@ msgstr "" "Lidhja u hodh poshtë - sigurohuni se keni dhënë kredencialet e duhura dhe se " "shërbyesi është në funksionim." -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "Lidhja u hodh poshtë" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "S’u gjet depo" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "Frazëkalim i pasaktë fshehtëzimesh" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "Hyrje SSH e mohuar" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" "Shtegu i depos s’është i zbrazët, as është një depo ekzistuese " "kopjeruajtjesh." -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "Depoja ekzistuese s’është e fshehtëzuar." -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "Depozitë {box_name}" @@ -493,7 +493,7 @@ msgid "Create Location" msgstr "Krijoni Vendndodhje" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "Krijoni Depo" @@ -736,7 +736,7 @@ msgstr "Çmontimi dështoi!" msgid "Mounting failed" msgstr "Montimi dështoi" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -748,7 +748,7 @@ msgstr "" "audio, video dhe dokumente PDF mund të bëhet paraparje te shfletuesi. " "Kartelave që ndahen me të tjerë mund t’u caktohet skadim pas një periudhe." -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -760,7 +760,7 @@ msgstr "" "një fjalëkalim, mund t’ua jepni përdoruesve të cilët duhet të kenë lejet " "përkatëse." -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -772,39 +772,39 @@ msgstr "" "t’ju lejojë të shfuqizoni më vonë hyrje për një persona apo një grup, duke " "hequr nga lista fjalëkalimin përkatës." -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "Lexoni një kartelë, nëse zotëroni një lidhje web për te kartela" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "Krijoni ose ngarkoni kartela" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "Paraqit krejt kartelat dhe lidhjet e tyre" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "Fshini kartela" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "Administroni kartela: kyçni/shkyçni kartela" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "Askush, fjalëkalimi është përherë i domosdoshëm" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "Shfaqni dhe lexoni krejt kartelat" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "bepasty" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "Dhënie Kartelash & Copëzash" @@ -818,7 +818,7 @@ msgstr "Leje për përdorues anonimë, të cilët s’kanë dhënë fjalëkalim. #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "Leje" @@ -852,35 +852,35 @@ msgstr "S’ka fjalëkalime aktualisht të formësuar." #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "Fjalëkalim" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "përgjegjës" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "përpunues" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "shikues" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "Lexoni" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "Krijoje" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "Listë" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -892,35 +892,35 @@ msgstr "Listë" msgid "Delete" msgstr "Fshije" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "Përgjegjës" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "Formësimi u përditësua." -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "Ndodhi një gabim gjatë formësimit." -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "U shtua fjalëkalim." -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "Shtoni Fjalëkalim" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "Fjalëkalimi u fshi." -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." @@ -929,7 +929,7 @@ msgstr "" "Përkatësish (DNS), dhe të ftilloni kërkesa DNS për pajisjet e përdoruesve " "tuaj në rrjetin tuaj." -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -940,33 +940,25 @@ msgstr "" "për makina të tjera në rrjetin vendor. Gjithashtu është i papërputhshëm me " "ndarje lidhje Interneti me të tjerë që nga {box_name}." -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "BIND" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "Shërbyes Emrash Përkatësish" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "Përcjellës" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" "Një listë shërbyesish DNS, ndarë nga një hapësirë, te të cilët do të " "përcillen kërkesat" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "Aktivizo DNSSEC" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "Aktivizo Zgjerime Sigurie Sistemi Emrash Shërbyesish" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "Shërbim Përkatësish" @@ -998,19 +990,20 @@ msgstr "Adresa IP" msgid "Refresh IP address and domains" msgstr "Rifresko adresë IP dhe përkatësi" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "Formësimi u përditësua" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -1021,7 +1014,7 @@ msgstr "" "koleksioni juaj i e-librave. E-librat mund t’i depozitoni në {box_name} " "tuaj, t’i lexoni që nga interneti ose nga cilado pajisje juaj." -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -1037,7 +1030,7 @@ msgstr "" "fundit të leximit, faqerojtës, dhe tekst të theksuar. Aktualisht nuk " "mbulohet shpërndarje lënde duke përdorur OPDS." -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1046,29 +1039,31 @@ msgstr "" "gjendje të përdorin aplikacionin. Krejt përdoruesit e lejuar mund të hyjnë " "në të gjitha bibliotekat." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Përdorni biblioteka calibre e-librash" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Bibliotekë E-librash" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Emër i bibliotekës së re" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" +"Vetëm shkronja të alfabetit të anglishtes, numra dhe shenjat _ . dhe - pa " +"hapësira apo shenja speciale. Shembull: Mediateka_ime_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Ka tashmë një bibliotekë me atë emër." @@ -1116,20 +1111,20 @@ msgstr "Kalo te biblioteka %(library)s" msgid "Delete library %(library)s" msgstr "Fshije bibliotekën %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Biblioteka u krijua." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Ndodhi një gabim teksa krijohej biblioteka." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} u fshi." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "S’u fshi dot {name}: {error}" @@ -1179,7 +1174,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Administrim Shërbyesi" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1187,18 +1182,18 @@ msgstr "" "Këtu mund të caktoni disa nga mundësitë e përgjithshme të formësimit, bie " "fjala strehëemër, emër përkatësie, faqe hyrëse e sgërbyesit." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Formësim i Përgjithshëm" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Formësoni" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1291,67 +1286,69 @@ msgstr "Shfaq aplikacione dhe veçori që lypin dije më teknike." #: plinth/modules/config/forms.py:104 msgid "System-wide logging" -msgstr "" +msgstr "Regjistrim për gjithë sistemin" #: plinth/modules/config/forms.py:105 msgid "Disable logging, for privacy" -msgstr "" +msgstr "Çaktivizo regjistrim, për privatësi" #: plinth/modules/config/forms.py:107 msgid "Keep some in memory until a restart, for performance" -msgstr "" +msgstr "Mbaj ca në kujtesë, deri në një rinisje, për punim më të mirë" #: plinth/modules/config/forms.py:110 msgid "Write to disk, useful for debugging" -msgstr "" +msgstr "Shkruaje në disk, e dobishme për diagnostikim" #: plinth/modules/config/forms.py:112 msgid "" "Logs contain information about who accessed the system and debug information " "from various services" msgstr "" +"Regjistrat përmbajnë informacion se cilët kanë hyrë në sistem dhe hollësi " +"diagnostikimi nga shërbime të ndryshme" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Gabim në caktim strehëemri: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Strehëemri u caktua" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Gabim në caktimin e emrin të përkatësisë: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Emri i përkatësisë u caktua" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Gabim në caktim faqeje hyrëse shërbyesi: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Faqja hyrëse e shërbyesit u caktua" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Gabim në ndryshimin e mënyrës së thelluar: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Me aplikacione dhe veçori të thelluara shfaqur" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Me aplikacione dhe veçori të thelluara fshehur" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1364,7 +1361,7 @@ msgstr "" "thirrje mes palësh që, përndryshe, s’janë në gjendje të lidhen me njëri-" "tjetrin." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse, ose ejabberd duhen formësuar me hollësitë e dhëna këtu." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Ndihmës VoIP" @@ -1437,11 +1434,11 @@ msgstr "Gabim në ujdisje zone kohore: {exception}" msgid "Time zone set" msgstr "Zona kohore u caktua" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge është një klient BitTorrent që përmban një UI Web." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1449,16 +1446,16 @@ msgstr "" "Fjalëkalimi parazgjedhje është “deluge”, por duhet të bëni hyrjen me të dhe " "ta ndryshoni menjëherë pas aktivizimit të këtij shërbimi." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Shkarkoni kartela duke përdorur aplikacione BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Klient Web BitTorrent" @@ -1586,7 +1583,7 @@ msgstr "Përfundim" msgid "Diagnostic Test" msgstr "Test Diagnostikimesh" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1598,7 +1595,7 @@ msgstr "" "Internet. Kjo do t’u pengojë të tjerëve të gjejnë shërbime të cilat ofrohen " "nga ky {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1616,14 +1613,7 @@ msgstr "" "emrin tuaj DNS me IP-në e re, dhe nëse dikush në Internet kërkon për emrin " "tuaj DNS, do të marrë një përgjigje me adresën tuaj aktuale IP." -#: plinth/modules/dynamicdns/__init__.py:41 -#, fuzzy -#| msgid "" -#| "If you are looking for a free dynamic DNS account, you may find a free " -#| "GnuDIP service at ddns.freedombox.org or you may find free update URL " -#| "based services at " -#| "freedns.afraid.org." +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1631,16 +1621,16 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" "Nëse po kërkoni për një llogari falas DNS-je dinamike, mund të gjeni një " -"shërbim GnuDIP të lirë, te ddns.freedombox.org</a>, ose mund të gjeni shërbime të " -"lira me bazë përditësim URL-je, te <a href=\" target=\"_blank\"> freedns." -"afraid.org." +"shërbim GnuDIP të lirë, te ddns.freedombox.org ose mund të gjeni shërbime të lira me " +"bazë përditësim URL-je, te freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Klient DNS Dinamik" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Emër Dinamik Përkatësie" @@ -1720,10 +1710,8 @@ msgid "GnuDIP" msgstr "GnuDIP" #: plinth/modules/dynamicdns/forms.py:57 -#, fuzzy -#| msgid "other update URL" msgid "Other update URL" -msgstr "tjetër URL përditësimesh" +msgstr "Tjetër URL përditësimesh" #: plinth/modules/dynamicdns/forms.py:59 msgid "Service Type" @@ -1767,15 +1755,13 @@ msgid "Use IPv6 instead of IPv4" msgstr "Përdor IPv6, në vend se IPv4" #: plinth/modules/dynamicdns/forms.py:123 -#, fuzzy -#| msgid "secrets required" msgid "This field is required." -msgstr "lyp të fshehta" +msgstr "Kjo fushë është e domosdoshme." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1799,52 +1785,38 @@ msgid "Last update" msgstr "Përditësimi i fundit më" #: plinth/modules/dynamicdns/templates/dynamicdns.html:21 -#, fuzzy -#| msgid "IP address" msgid "IP Address" msgstr "Adresë IP" #: plinth/modules/dynamicdns/templates/dynamicdns.html:32 -#, fuzzy -#| msgid "Access" msgid "Success" -msgstr "Hyrje" +msgstr "Sukses" #: plinth/modules/dynamicdns/templates/dynamicdns.html:36 -#, fuzzy -#| msgid "failed" msgid "Failed" -msgstr "dështoi" +msgstr "Dështoi" #: plinth/modules/dynamicdns/templates/dynamicdns.html:52 -#, fuzzy -#| msgid "No libraries available." msgid "No status available." -msgstr "S’ka biblioteka." +msgstr "S’ka gjendje të ditur." #: plinth/modules/dynamicdns/views.py:24 plinth/modules/dynamicdns/views.py:26 -#, fuzzy -#| msgid "Connection Name" msgid "Connection timed out" -msgstr "Emër Lidhjeje" +msgstr "Lidhjes i mbaroi koha" #: plinth/modules/dynamicdns/views.py:25 msgid "Could not find server" -msgstr "" +msgstr "S’u gjet dot shërbyes" #: plinth/modules/dynamicdns/views.py:27 -#, fuzzy -#| msgid "Delete connection" msgid "Server refused connection" -msgstr "Fshije lidhjen" +msgstr "Shërbyesi hodhi poshtë lidhjen" #: plinth/modules/dynamicdns/views.py:28 -#, fuzzy -#| msgid "Enable auto-update" msgid "Already up-to-date" -msgstr "Aktivio vetëpërditësim" +msgstr "I përditësuar tashmë" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1852,7 +1824,7 @@ msgstr "" "XMPP është një protokoll i hapët dhe i standardizuar komunikimesh. Këtu mund " "të vini në punë dhe formësoni shërbyesin tuaj XMPP, të quajtur ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client me hyrje {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn, ose formësoni një shërbyes " "të jashtëm." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Shërbyes Fjalosjesh" #: plinth/modules/ejabberd/forms.py:19 -#, fuzzy -#| msgid "Domain Names" msgid "Domain names" -msgstr "Emra Përkatësish" +msgstr "Emra përkatësish" #: plinth/modules/ejabberd/forms.py:21 msgid "" "Domains to be used by ejabberd. Note that user accounts are unique for each " "domain, and migrating users to a new domain name is not yet implemented." msgstr "" +"Përkatësi për t’u përdorur nga ejabberd. Kini parasysh se llogaritë e " +"përdoruesve janë unike për çdo përkatësi dhe migrimi i përdoruesve te një " +"emër i ri përkatësie s’është sendërtuar ende." #: plinth/modules/ejabberd/forms.py:26 msgid "Enable Message Archive Management" @@ -2005,22 +1978,31 @@ msgstr "" "Përkatësinë tuaj mund ta ujdisni te faqja Formësoni e sistemit." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" +"Kjo është një zgjidhje e plotë shërbyes email që përdor Postfix, Dovecot dhe " +"Rspamd. Postfix-i dërgon dhe merr email-e. Dovecot u lejon klientëve email " +"të përdorin kutinë tuaj postare përmes IMAP apo POP3. Rspamd trajton " +"mesazhet e padëshiruar." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " "restrict outgoing email. Some lift the restriction after an explicit " "request. See manual page for more information." msgstr "" +"Shërbyesi email aktualisht nuk funksionon me mjaft shërbime të lira " +"përkatësish, përfshi ato të FreedomBox Foundation. Gjithashtu mjaft ISP " +"kufizojnë email-t e dërguar. Disa prej tyre e heqin kufizimin pas një " +"kërkese shprehimisht për këtë. Për më tepër hollësi, shihni faqen e " +"doracakut." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2029,8 +2011,14 @@ msgid "" "Necessary aliases such as \"postmaster\" are automatically created pointing " "to the first admin user." msgstr "" +"Çdo përdorues në {box_name} merr një adresë email të ngjashme me " +"përdorues@përkatësiaime.shembull. Do të marrë gjithashtu email nga krejt " +"adresat që duken si përdorues+foo@përkatësiaime.shembull. Më tej, mund të " +"shtojë aliase te adresa e tij email. Aliase të nevojshëm, të tillë si " +"“postmaster” krijohen automatikisht dhe shpien te i pari përdorues " +"përgjegjës." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2038,7 +2026,7 @@ msgstr "" "Aplikacioni Roundcube furnizon " "ndërfaqe web për përdoruesit për të përdorur email-in." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2054,16 +2042,12 @@ msgid "Email Server" msgstr "Shërbyes Email-i" #: plinth/modules/email/__init__.py:83 -#, fuzzy -#| msgid "Manage Aliases" msgid "My Email Aliases" -msgstr "Administroni Aliase" +msgstr "Aliaset e Mi Email" #: plinth/modules/email/__init__.py:84 -#, fuzzy -#| msgid "Manage Aliases" msgid "Manage Aliases for Mailbox" -msgstr "Administroni Aliase" +msgstr "Administroni Aliase për Kuti postare" #: plinth/modules/email/forms.py:25 msgid "Primary domain" @@ -2137,7 +2121,7 @@ msgstr "Administroni Të Padëshiruarat" #: plinth/modules/email/templates/email.html:22 msgid "DNS Records" -msgstr "" +msgstr "Zëra DNS" #: plinth/modules/email/templates/email.html:25 msgid "" @@ -2147,19 +2131,19 @@ msgstr "" #: plinth/modules/email/templates/email.html:36 msgid "TTL" -msgstr "" +msgstr "TTL" #: plinth/modules/email/templates/email.html:37 msgid "Class" -msgstr "" +msgstr "Klasë" #: plinth/modules/email/templates/email.html:39 msgid "Priority" -msgstr "" +msgstr "Përparësi" #: plinth/modules/email/templates/email.html:40 msgid "Weight" -msgstr "" +msgstr "Madhësi" #: plinth/modules/email/templates/email.html:41 #: plinth/modules/minetest/templates/minetest.html:18 @@ -2168,9 +2152,9 @@ msgstr "Portë" #: plinth/modules/email/templates/email.html:42 msgid "Host/Target/Value" -msgstr "" +msgstr "Strehë/Objektiv/Vlerë" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2181,7 +2165,7 @@ msgstr "" "në rrjet te {box_name} juaj. Mbajta e një firewall-i të aktivizuar dhe të " "formësuar si duhet ul rrezikun e kërcënimeve të sigurisë nga Interneti." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Firewall" @@ -2201,53 +2185,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Portë {name} ({details}) jo e përdorshme për rrjete të brendshëm" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Demoni i firewall-it s’është vënën në punë. Ju lutemi, vëreni në punë. " -"Firewall-i vjen i aktivizuar, si parazgjedhje, në %(box_name)s. Në çfarëdo " -"sistemi me bazë Debian (si edhe %(box_name)s) mund ta vini në punë duke " -"përdorur urdhrin “service firewalld start”, ose, në rast të një sistemi me " -"systemd, me “systemctl start firewalld”." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Shërbim/Portë" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "E aktivizuar" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "E çaktivizuar" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "E lejuar" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "E lejuar (vetëm së brendshmi)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "E lejuar (vetëm së jashtmi)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "E bllokuar" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2257,13 +2227,13 @@ msgstr "" "ky lejohet edhe te firewall-i, dhe kur e çaktivizoni, çaktivizohet " "gjithashtu edhe te firewall-i." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Të thelluara" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2317,7 +2287,7 @@ msgstr "Nis Ujdisjen" msgid "Setup Complete" msgstr "Ujdisje e Plotësuar" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2335,7 +2305,7 @@ msgstr "" "rreshti urdhrash ose përmes klientësh të shumta grafikë të gatshëm. Dhe mund " "ta ndani kodin tuaj me njerëz anembanë botës." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2343,67 +2313,67 @@ msgstr "" "Për të mësuar më tepër se si të përdoret Git, vizitoni përkujdesore Git-i." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Hyrje për shkrim-lexim në depo Git" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Strehim i Thjeshtë Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "URL e pavlefshme depoje." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Emër i pavlefshëm depoje." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "Emër i një depoje të re, ose URL për të importuar një depo ekzistuese." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Përshkrim i depos" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Opsionale, për shfaqje në Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Emër të zoti depoje" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Depo private" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Në këtë depo mund të hyjnë vetëm përdorues të autorizuar." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Ka tashmë një depo me këtë emër." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Emër i depos" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Një varg alfanumerik që identifikon në mënyrë unike një depo." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Degë parazgjedhje" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb e shfaq këtë si një degë parazgjedhje." @@ -2447,19 +2417,19 @@ msgstr "Fshi Depon Git %(name)s" msgid "Delete this repository permanently?" msgstr "Të fshihet kjo depo përgjithmonë?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Depoja u krijua." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Ndodhi një gabim teksa krijohej depoja." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Depoja u përpunua." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Përpunoni depon" @@ -2634,38 +2604,40 @@ msgstr "Mësoni më tepër…" #: plinth/modules/help/templates/help_contribute.html:46 msgid "How can I help?" -msgstr "" +msgstr "Si mund t’ju ndihmoj?" #: plinth/modules/help/templates/help_contribute.html:48 msgid "" "Below is a list of opportunities for contributing to Debian. It has been " "filtered to only show packages that are installed on this system." msgstr "" +"Më poshtë gjendet një listë mundësish për të dhënë ndihmesë te Debian. Është " +"filtruar për të shfaqur vetëm paketa që janë të instaluara në këtë sistem." #: plinth/modules/help/templates/help_contribute.html:59 msgid "Show issues" -msgstr "" +msgstr "Shfaq çështje" #: plinth/modules/help/templates/help_contribute.html:63 msgid "Packages that will be removed from Debian testing" -msgstr "" +msgstr "Paketa që do të hiqen nga dega Debian testing" #: plinth/modules/help/templates/help_contribute.html:69 #: plinth/modules/help/templates/help_contribute.html:85 msgid "source package:" -msgstr "" +msgstr "paketë burim:" #: plinth/modules/help/templates/help_contribute.html:80 msgid "Packages that are not in Debian testing" -msgstr "" +msgstr "Paketa që s’janë pjesë e degës Debian testing" #: plinth/modules/help/templates/help_contribute.html:92 msgid "Good first issues for beginners" -msgstr "" +msgstr "Çështje të përshtatshme për fillestarë" #: plinth/modules/help/templates/help_contribute.html:104 msgid "Issues for which the package maintainer has requested help" -msgstr "" +msgstr "Çështje për të cilat mirëmbajtësi i paketës ka kërkuar ndihmë" #: plinth/modules/help/templates/help_feedback.html:12 #, python-format @@ -2824,7 +2796,7 @@ msgstr "Mbi {box_name}" msgid "{box_name} Manual" msgstr "Doracak për {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2836,7 +2808,7 @@ msgstr "" "dërguar trafik të fshehtëzuar, përmes një rrjeti të mbajtur në këmbë nga " "vullnetarë, të shpërndarë anembanë botës." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2844,26 +2816,26 @@ msgstr "" "Më më tepër informacion rreth I2P-së mund të gjeni që nga faqja hyrëse e vetë projektit." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" "Vizita e parë te ndërfaqja web e dhënë do të fillojë procesin e formësimit." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Administroni aplikacion I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Rrjet Anonimiteti" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "Ndërmjetës I2P" @@ -2909,7 +2881,7 @@ msgstr "" "një rrjet “peer-to-peer”. Shkarkoni kartela duke shtuar rrëkeza, ose krijoni " "një rrëkezë të re për të ndarë një kartelë me të tjerët." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2919,7 +2891,7 @@ msgstr "" "markup-i të lehta, përfshi Markdown, dhe funksione të rëndomtë blogimi, bie " "fjala, komente dhe prurje RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2933,15 +2905,15 @@ msgstr "" "ekzistueset. Te Formësim Përdoruesish mund të " "ndryshoni këto leje ose të shtoni përdorues të rinj." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki dhe Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Shihni dhe përpunoni aplikacione wiki" @@ -2997,43 +2969,43 @@ msgstr "" "Ky veprim do të heqë krejt postimet, faqet dhe komentet, përfshi historik " "rishikimesh. Të fshihet përgjithmonë kjo wiki ose ky blog?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "U krijua wiki {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "S’u krijua dot wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "U krijua blogu {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "S’u krijua dot blogu: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} u fshi." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "S’u fshi dot {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" "infinoted është një shërbyes për Gobby, një përpunues tekstesh në " "bashkëpunim." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3044,11 +3016,11 @@ msgstr "" "klientin desktop, dhe instalojeni. Mandej nisni Gobby-n dhe përzgjidhni " "“Lidhu me Shërbyes” dhe jepni emrin e përkatësisë së {box_name} tuaj." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Shërbyes Gobby" @@ -3071,16 +3043,18 @@ msgstr "" #: plinth/modules/janus/__init__.py:22 msgid "Janus is a lightweight WebRTC server." -msgstr "" +msgstr "Janus është një shërbyes WebRTC i peshës së lehtë." #: plinth/modules/janus/__init__.py:23 msgid "A simple video conference room is included." -msgstr "" +msgstr "Përfshihet një dhomë e thjeshtë konferencash me video." #: plinth/modules/janus/__init__.py:25 #, python-brace-format msgid "Coturn is required to use Janus." msgstr "" +"Coturn është i domosdoshëm për të përdorur " +"Janus-in." #: plinth/modules/janus/__init__.py:41 msgid "Janus" @@ -3088,15 +3062,15 @@ msgstr "Janus" #: plinth/modules/janus/__init__.py:43 msgid "Video Room" -msgstr "" +msgstr "Dhomë Me Video" #: plinth/modules/janus/manifest.py:7 msgid "Janus Video Room" -msgstr "" +msgstr "Janus Video Room" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Hollësi licence JavaScript" @@ -3116,7 +3090,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Klient Fjalosjesh" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3131,7 +3105,7 @@ msgstr "" "përkatësi të pranishme. Këtë e bën duke dëshmuar për veten se është i zoti " "i një përkatësie nga Let’s Encrypt, një autoritet dëshmish (AD)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3144,15 +3118,15 @@ msgstr "" "pajtohuni me Marrëveshje " "Pajtimtari Let’s Encrypt before using this service." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Dëshmi" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "S’mund të testojë: S’ka përkatësi të formësuara." @@ -3217,7 +3191,7 @@ msgstr "" "S’ka përkatësi të formësuara. Formësoni " "përkatësi, që të jetë në gjendje të marrë dëshmi për to." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3226,34 +3200,34 @@ msgstr "" "Dëshmi e shfuqizuar me sukses për përkatësinë {domain}.Kjo mund të dojë ca " "çaste të hyjë në fuqi." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "S’u arrit të shfuqizohet dëshmi për përkatësinë {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Dëshmi e marrë me sukses për përkatësinë {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "S’u arrit të merret dëshmi për përkatësinë {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Dëshmi e fshirë me sukses për përkatësinë {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "S’u arrit të fshihet dëshmi për përkatësinë {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3270,7 +3244,7 @@ msgstr "" "funksionojë. Përmes federimi, përdoruesit në një shërbyes të dhënë Matrix " "mund të bisedojnë me përdorues në krejt shërbyesit e tjerë Matrix." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3280,7 +3254,7 @@ msgstr "" "aplikacionin Coturn, ose formësoni një shërbyes " "të jashtëm." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3388,7 +3362,7 @@ msgstr "" "Ju lutemi, kaloni te Let's Encrypt, që " "të merrni një të tillë." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3401,7 +3375,7 @@ msgstr "" "strehuar sajt të llojit wiki, për të mbajtur shënime ose për të bashkëpunuar " "me shokë në projekte." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3416,7 +3390,7 @@ msgstr "" "href=\"/mediawiki/index.php/Special:CreateAccount\">Special:CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3424,12 +3398,12 @@ msgstr "" "Cilido me një lidhje për te kjo wiki mund ta lexojë atë. Ndryshime te lënda " "mund të bëjnë vetëm përdorues që kanë bërë hyrjen në llogaritë e tyre." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3438,10 +3412,6 @@ msgid "Administrator Password" msgstr "Fjalëkalim Përgjegjësi" #: plinth/modules/mediawiki/forms.py:27 -#, fuzzy -#| msgid "" -#| "Set a new password for MediaWiki's administrator account (admin). Leave " -#| "this field blank to keep the current password." msgid "" "Set a new password for MediaWiki's administrator account (admin). The " "password cannot be a common one and the minimum required length is " @@ -3449,30 +3419,27 @@ msgid "" "password." msgstr "" "Caktoni një fjalëkalim të ri për llogarinë e përgjegjësit të MediaWiki-it " -"(admin). Që të mbani fjalëkalimin e tanishëm, lëreni të zbrazët këtë fushë." +"(admin). Fjalëkalimi s’mund të jetë i rëndomtë dhe gjatësia më e pakët e " +"domosdoshme është 10 shenja. Që të mbani fjalëkalimin e " +"tanishëm, lëreni të zbrazët këtë fushë." #: plinth/modules/mediawiki/forms.py:35 -#, fuzzy -#| msgid "" -#| "Used by MediaWiki to generate URLs that point to the wiki such as in " -#| "footer, feeds and emails." msgid "" "Used by MediaWiki to generate URLs that point to the wiki such as in footer, " "feeds and emails. Examples: \"myfreedombox.example.org\" or \"example.onion" "\"." msgstr "" "E përdorur nga MediaWiki për të prodhuar URL-ra që shpien te wiki, p.sh., te " -"fundfaqja, prurjet ose email-e." +"fundfaqja, prurjet ose email-e. Shembuj: “myfreedombox.example.org”, ose " +"“example.onion”." #: plinth/modules/mediawiki/forms.py:41 -#, fuzzy -#| msgid "Kite name" msgid "Site Name" -msgstr "Emër Kite-i" +msgstr "Emër Sajti" #: plinth/modules/mediawiki/forms.py:42 msgid "Name of the site as displayed throughout the wiki." -msgstr "" +msgstr "Emër i sajtit siç shfaqet nëpër wiki." #: plinth/modules/mediawiki/forms.py:46 msgid "Enable public registrations" @@ -3516,46 +3483,40 @@ msgid "Password updated" msgstr "Fjalëkalimi u përditësua" #: plinth/modules/mediawiki/views.py:59 -#, fuzzy -#| msgid "Password used to encrypt data. Must match server password." msgid "Password update failed. Please choose a stronger password" msgstr "" -"Fjalëkalim i përdorur për të fshehtëzuar të dhëna. Duhet të përputhet me " -"fjalëkalimin e shërbyesit." +"Përditësimi i fjalëkalimit dështoi. Ju lutemi, zgjidhni një fjalëkalim më të " +"fortë" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Regjistrimet publike u aktivizuan" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Regjistrimet publike u çaktivizuan" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Mënyra private u aktivizua" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Mënyra private u çaktivizua" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Lëkurçja parazgjedhje u ndryshua" -#: plinth/modules/mediawiki/views.py:102 -#, fuzzy -#| msgid "Domain name set" +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" -msgstr "Emri i përkatësisë u caktua" +msgstr "Emri i përkatësisë u përditësua" -#: plinth/modules/mediawiki/views.py:106 -#, fuzzy -#| msgid "Domain name set" +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" -msgstr "Emri i përkatësisë u caktua" +msgstr "Emri i sajtit u përditësua" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3569,11 +3530,11 @@ msgstr "" "lypset një klient Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Bankëprovë Blloqesh" @@ -3626,7 +3587,7 @@ msgstr "" msgid "Address" msgstr "Adresë" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3738,17 +3699,19 @@ msgstr "" #: plinth/modules/mumble/forms.py:40 msgid "Set a password to join the server" -msgstr "" +msgstr "Që të bëheni pjesë e një shërbyesi, caktoni një fjalëkalim" #: plinth/modules/mumble/forms.py:42 msgid "" "Set a password that is required to join the server. Leave empty to use the " "current password." msgstr "" +"Caktoni një fjalëkalim që është i domosdoshëm për të hyrë te shërbyesi. Për " +"të përdorur fjalëkalimin e tanishëm, lëreni të zbrazët." #: plinth/modules/mumble/forms.py:48 msgid "Set the name for the root channel" -msgstr "" +msgstr "Caktoni emrin e kanalit rrënjë" #: plinth/modules/mumble/forms.py:52 msgid "" @@ -3769,14 +3732,12 @@ msgid "SuperUser password successfully updated." msgstr "Fjalëkalimi i superpërdoruesit u përditësua me sukses." #: plinth/modules/mumble/views.py:48 -#, fuzzy -#| msgid "Password added." msgid "Join password changed" -msgstr "U shtua fjalëkalim." +msgstr "Fjalëkalimi i ardhjes u ndryshua" #: plinth/modules/mumble/views.py:53 msgid "Root channel name changed." -msgstr "" +msgstr "Emri i kanalit rrënjë ndryshoi" #: plinth/modules/names/__init__.py:22 #, python-brace-format @@ -3812,7 +3773,7 @@ msgstr "Shell i Sigurt" msgid "Services" msgstr "Shërbime" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3820,7 +3781,7 @@ msgstr "" "Formësoni pajisje rrjeti. Lidhuni në Internet përmes Ethernet-i, Wi-Fi ose " "PPPoE. Ndajeni atë lidhje me pajisje të tjera në rrjet." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3828,7 +3789,7 @@ msgstr "" "Pajisjet e administruara përmes metodash të tjera mund të mos jenë të " "pranishme për formësim këtu." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Rrjete" @@ -4263,7 +4224,7 @@ msgstr "Përpunoni lidhjen" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Përpunoni" @@ -4368,7 +4329,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Metodë" @@ -4384,7 +4345,7 @@ msgstr "Shërbyes DNS" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Gjendje" @@ -4397,7 +4358,7 @@ msgid "This connection is not active." msgstr "Kjo lidhje s’është aktive." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Siguri" @@ -4984,7 +4945,7 @@ msgstr "Lidhja {name} u fshi." msgid "Failed to delete connection: Connection not found." msgstr "S’u arrit të fshihet lidhje: S’u gjet lidhje." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -5001,20 +4962,20 @@ msgstr "" "brendshme të dhëna nga {box_name}. Mund të hyni edhe në Internet përmes " "{box_name}-it, për më tepër siguri dhe anonimitet." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Lidhuni me shërbime VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Rrjet Virtual Privat" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -5025,58 +4986,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Migroje në ECC" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Instalimi juaj OpenVPN aktualisht përdor RSA. Kalimi nën Kriptografinë " -"moderne Kurbash Eliptike përmirëson shpejtësinë e vendosjes së një lidhjeje " -"dhe sigurinë. Ky veprim është i pakthyeshëm. Në shumicën e kompjuterave " -"njëskedësh ha vetëm pak minuta." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Krejt instalimet e reja të OpenVPN në %(box_name)s do të përdorin KKE (ECC), " -"si parazgjedhje. Rekomandojmë migrim sa më shpejt të jetë e mundur." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Kujdes: Profile klientësh ekzistues do të bëhen të pavlefshme nga ky " -"veprim. Krejt përdoruesit OpenVPN te %(box_name)s duhet të shkarkojnë " -"profilet e tyre të rinj. Për t’u lidhur me këtë shërbyes, duhen përdorur " -"klientë OpenVPN të përputhshëm me KKE (ECC)." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Migroje" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "Për t’u lidhur me VPN-në e %(box_name)s-it, duhet të shkarkoni një profil " @@ -5084,18 +5008,19 @@ msgstr "" "desktop. Ka klientë OpenVPN për shumicën e platformave. Për klientë të " "rekomanduar dhe udhëzime se si të formësohen ata, klikoni “Mësoni më tepër…”." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Profili është specifik për çdo përdorues të %(box_name)s. Mbajeni të " "fshehtë." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Shkarko profilin tim" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5108,19 +5033,19 @@ msgstr "" "{box_name}-it tuaj janë të pakapshme nga pjesa tjetër e Internetit. Kjo " "përfshin gjendjet vijuese:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} gjendet pas një firewall-i të kufizuar." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} është i lidhur te një rrugëzues (pa fill), të cilin nuk e " "kontrolloni ju." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5128,7 +5053,7 @@ msgstr "" "ISP-ja juaj s’ju furnizon një adresë IP të jashtme dhe në vend të kësaj ju " "jep lidhje Internet përmes NAT-i." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5136,11 +5061,11 @@ msgstr "" "ISP-ja juaj s’ju furnizon një adresë IP statike dhe adresa juaj IP ndryshon " "sa herë që lidheni në Internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "ISP-ja juaj kufizon lidhjet ardhëse." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5155,23 +5080,23 @@ msgstr "" "të ardhmen mund të jetë e mundshme të përdorni {box_name}-in e një shokut " "tuaj për këtë." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "E dukshme Publikisht" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Përkatësi PageKite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Përkatësi shërbyesi" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5179,32 +5104,32 @@ msgstr "" "Përzgjidhni shërbyesin tuaj <em>pagekite</em>. Vëreni si " "“pagekite.net”, që të përdorni shërbyesin parazgjedhje pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Portë shërbyesi" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" "Portë e shërbyesit tuaj <em>pagekite</em> (parazgjedhje: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Emër Kite-i" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Shembull: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Emër <em>pagekite</em> i pavlefshëm" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "E fshehtë Kite-i" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5213,35 +5138,35 @@ msgstr "" "fshehta parazgjedhje për llogarinë tuaj, nëse te <em>pagekite</" "em>-i s’është caktuar e fshehtë." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokoll" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "portë e jashtme (frontend)" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "portë e brendshme (freedombox)" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Aktivizo Nënpërkatësi" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "U fshi shërbimin vetjak" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Ky shërbimi është tashmë i gatshëm si shërbim standard." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "U shtua shërbim vetjak" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Ka tashmë një shërbim të tillë" @@ -5279,29 +5204,29 @@ msgstr "" "përcaktoni këtu. Për shembull, HTTPS në porta të tjera nga 443 dihet se " "shkakton probleme." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Shërbyes (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Sajti do të gjendet në http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Shërbyes (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Sajti do të gjendet në https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Shell i Sigurt (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5353,8 +5278,8 @@ msgstr "" "Aktualisht po xhiron një instalim ose përmirësim. Shihni mundësinë e " "pritjes, deri sa të përfundohet, përpara fikjes apo rinisjes." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Rinise" @@ -5404,6 +5329,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Fike Tani" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5416,13 +5374,7 @@ msgstr "" "tjera hedhurina të papëlqyeshme Internet. " #: plinth/modules/privoxy/__init__.py:28 -#, fuzzy, python-brace-format -#| msgid "" -#| "You can use Privoxy by modifying your browser proxy settings to your " -#| "{box_name} hostname (or IP address) with port 8118. While using Privoxy, " -#| "you can see its configuration details and documentation at http://config.privoxy.org/ or http://p.p." +#, python-brace-format msgid "" "You can use Privoxy by modifying your browser proxy settings to your " "{box_name} hostname (or IP address) with port 8118. Only connections from " @@ -5433,9 +5385,10 @@ msgid "" msgstr "" "Privoxy-në mund ta përdorni duke ndryshuar rregullimet e shfletuesit tuaj " "për ndërmjetës si strehëemri i {box_name}-it tuaj (ose adresa IP) me portë " -"8118. Kur përdoret Privoxy, hollësitë mbi formësimin e tij dhe dokumentim " -"për të mund të shihni te http://config." -"privoxy.org/ ose http://p.p." +"8118. Lejohen vetëm lidhje prej adresash IP rrjeti vendor. Kur përdoret " +"Privoxy, hollësitë mbi formësimin e tij dhe dokumentim për të mund të shihni " +"te http://config.privoxy.org/ ose " +"http://p.p." #: plinth/modules/privoxy/__init__.py:51 msgid "Privoxy" @@ -5450,7 +5403,7 @@ msgstr "Ndërmjetës Web" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Hapni {url} me ndërmjetësin {proxy} në tcp{kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5467,7 +5420,7 @@ msgstr "" "në linjë dhe një ose më tepër klientë Quassel prej një desktopi ose celulari " "mund të përdoren për t’u lidhur dhe shkëputur prej tij." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your desktopi dhe celulari juaj." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Klient IRC" @@ -5491,7 +5444,7 @@ msgstr "Klient IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5507,7 +5460,7 @@ msgstr "" "Radicale mund të hyhet nga cilido përdorues me kredenciale hyrjeje në " "{box_name}." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5517,12 +5470,12 @@ msgstr "" "të ri dhe librash adresash. Nuk mbulon shtim veprimtarish ose kontaktesh, " "çka duhen bërë duke përdorur një tjetër klient." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Kalendar dhe Libër adresash" @@ -5596,7 +5549,7 @@ msgstr "" "e_freedombox-it.tuaj>) dhe emrin tuaj të përdoruesit. Klikimi mbi butonin " "e kërkimit do të shfaqë kalendarët dhe librat ekzistues të adresave." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Formësimi i të drejtave për hyrje u përditësua" @@ -5668,16 +5621,13 @@ msgid "" msgstr "" #: plinth/modules/rssbridge/__init__.py:23 -#, fuzzy, python-brace-format -#| msgid "" -#| "When enabled, Tiny Tiny RSS can be accessed by any user with a {box_name} login." +#, python-brace-format msgid "" "When enabled, RSS-Bridge can be accessed by any " "user belonging to the feed-reader group." msgstr "" -"Kur aktivizohet, Tiny Tiny RSS mund të përdoret nga cilido përdorues me kredenciale hyrjeje në {box_name}." +"Kur aktivizohet, RSS-Bridge mund të përdoret nga cilido përdorues pjesë e grupit të leximit të prurjeve." #: plinth/modules/rssbridge/__init__.py:27 #, python-brace-format @@ -5686,21 +5636,24 @@ msgid "" "follow various websites. When adding a feed, enable authentication and use " "your {box_name} credentials." msgstr "" +"RSS-Bridge-in mund ta përdorni me Tiny Tiny RSS " +"për të ndjekur sajte të ndryshëm. Kur shtohet një prurje, aktivizoni " +"mirëfilltësimin dhe përdorni kredencialet tuaj për {box_name}." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Lexoni dhe pajtohuni te prurje lajmesh" #: plinth/modules/rssbridge/__init__.py:48 #: plinth/modules/rssbridge/manifest.py:10 msgid "RSS-Bridge" -msgstr "" +msgstr "RSS-Bridge" #: plinth/modules/rssbridge/__init__.py:49 msgid "RSS Feed Generator" -msgstr "" +msgstr "Prodhues Prurjesh RSS" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5708,7 +5661,7 @@ msgstr "" "Samba lejon të ndani me të tjerë kartela dhe dosje mes FreedomBox-it dhe " "kompjuterave të tjerë në rrjetin tuaj vendor." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5722,11 +5675,11 @@ msgstr "" "{hostname}.local (në Linux dhe Mac). Ka tre lloje ndarjesh nga mund të " "zgjidhni " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Pjesë e hapët - e përdorshme nga cilido në rrjetin tuaj vendor." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5734,7 +5687,7 @@ msgstr "" "Pjesë grupi - e përdorshme vetëm nga përdorues të FreedomBox-it të cilët " "janë pjesë e grupit freedombox-share." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5742,15 +5695,15 @@ msgstr "" "Pjesë Home - cilido përdorues në grupin freedombox-share mund të ketë " "hapësirën e vet private." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Hyrje te ndarje private" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Depozitë Kartelash Në Rrjet" @@ -5838,15 +5791,15 @@ msgstr "Emër pjese" msgid "Action" msgstr "Veprim" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "Disk FreedomBox OS" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Pjesë e Hapët" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Pjesë Grupi" @@ -5872,7 +5825,7 @@ msgstr "Pjesa u çaktivizua." msgid "Error disabling share: {error_message}" msgstr "Gabim teksa çaktivizohej pjesë: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5880,7 +5833,7 @@ msgstr "" "Searx është një motor tejkërkimesh Internet që respekton privatësinë. " "Grumbullon dhe shfaq përfundime prej shumë motorësh kërkimi." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5888,41 +5841,41 @@ msgstr "" "Searx mund të përdoret për të shmangur gjurmim dhe profilizim nga motorë " "kërkimesh. Si parazgjedhje, nuk depoziton cookies." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Kërkoni në internet" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Kërkim në Web" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Kërkim i Parrezik" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Përzgjidhni filtrin familjar parazgjedhje për t’u zbatuar mbi përfundimet e " "kërkimit tuaj." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "I moderuar" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Strikt" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Lejo Hyrje Publike" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "Të lejohet ky aplikacion të përdoret nga cilido që mund ta kapë." @@ -6104,7 +6057,7 @@ msgstr "Faqerojtës" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6114,7 +6067,7 @@ msgstr "" "konceptuar të mbrojë trafikun tuaj Internet. Mund të përdoret për të " "anashkaluar filtrim dhe censurim Interneti." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6127,7 +6080,7 @@ msgstr "" "Pajisjet vendore mund të lidhen te ky ndërmjetës, dhe të dhënat e tyre do të " "fshehtëzohen dhe ndërmjetësohen përmes shërbyesit Shadowsocks." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6136,42 +6089,42 @@ msgstr "" "pajisjen, shfletuesin ose aplikacionin tuaj caktoni http://" "freedombox_address:1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Ndërmjetës SOCKS5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "E këshilluar" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Shërbyes" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Strehëemër ose adresë IP shërbyesi" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Numër porte shërbyesi" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Fjalëkalim i përdorur për të fshehtëzuar të dhëna. Duhet të përputhet me " "fjalëkalimin e shërbyesit." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Metodë fshehtëzimi. Duhet të përputhet me atë të caktuar te shërbyesi." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6180,15 +6133,15 @@ msgstr "" "Dhënia ju lejon të ndani nëpër internet kartela dhe dosje në {box_name}-in " "tuaj me grupe dhe përdorues të zgjedhur nga ju." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Dhënie" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Emër i pjesës" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6196,29 +6149,29 @@ msgstr "" "Një varg alfanumerik me të vogla, që identifikon në mënyrë unike një pjesë. " "Për shembull: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Shteg për te pjesa" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" "Shteg në disk për te dosja në këtë shërbyes të cilën doni ta ndani me të " "tjerët." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Pjesë publike" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Bëji kartelat në këtë dosje të passhme për këdo që ka lidhjen." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Grupet e përdoruesve që mund të lexojnë kartela te pjesa:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6226,11 +6179,11 @@ msgstr "" "Përdorues të grupit të përzgjedhur të përdoruesve do të jenë në gjendje të " "lexojnë kartelat te pjesa.." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Ka tashmë një pjesë me këtë emër." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Pjesët duhet të jenë ose publike, ose të ndara me të paktën një grup" @@ -6267,19 +6220,19 @@ msgstr "U shtua pjesë." msgid "Add Share" msgstr "Shtoni Pjesë" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "U përpunua pjesa." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Përpunoni Pjesë" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Pjesa u fshi." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6289,7 +6242,7 @@ msgstr "" "kartelash. Këto mund të përdoren për të kthyer sistemin te një gjendje e " "mëparshme e njohur si e mirë, në rast ndryshimesh të padëshiruar te sistemi." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6300,7 +6253,7 @@ msgstr "" "dhe gjithashtu para dhe pas instalimit të një software-i. Fotografimet e " "vjetra do të spastrohen automatikisht, në përputhje me rregullimet më poshtë." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for kopjeruajtjet, ngaqë mund të rikthehen vetëm në të " "njëjtën pjesë. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Depozito Fotografime" @@ -6414,7 +6367,7 @@ msgstr "Datë" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Fshi Fotografime" @@ -6468,58 +6421,58 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Prapaktheje te Fotografimi #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "krijuar dorazi" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "rrjedhë kohore" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Administroni Fotografime" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "U krijua fotografim." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "U përditësua formësim për depozitim fotografimesh" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Gabim veprimi: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "U fshinë fotografimet e përzgjedhur" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" "Fotografimi është aktualisht në përdorim. Ju lutemi, riprovoni më vonë." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "U kthye prapa te fotografimi #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Që të plotësohet prapakthimi, duhet rinisur sistemi." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Prapaktheje te Fotografim" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6531,7 +6484,7 @@ msgstr "" "një kompjuter i largët i autorizuar mund të kryejë punë administrimi, të " "kopjojë kartela ose të xhirojë shërbime të tjera." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Shërbyes Shelli të Sigurt (SSH)" @@ -6569,14 +6522,6 @@ msgstr "Algoritëm" msgid "Fingerprint" msgstr "Shenja gishtash" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "Mirëfilltësimi SSH me fjalëkalim u çaktivizua." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Mirëfilltësimi SSH me fjalëkalim u aktivizua." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Hyrje Njëshe" @@ -6589,7 +6534,7 @@ msgstr "Hyrje" msgid "Logged out successfully." msgstr "U dol me sukses." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6601,107 +6546,107 @@ msgstr "" "përdorim, të montoni dhe çmontoni media të heqshme, të zgjeroni pjesën " "rrënjë, etj." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Depozitë" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bajte" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Veprimi dështoi." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Veprimi u anulua." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Pajisja po çmontohet tashmë." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" "Veprimi nuk mbulohet, për shkak se mungon mbulimi për përudhësin/mjetin." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Veprimit i mbaroi koha." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "Veprimi do të zgjonte një disk që është në gjendjen “deep-sleep”." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Po përpiqet të çmontohet një pajisje që është e zënë." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Veprimi është anuluar tashmë." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "I paautorizuar për kryerjen e veprimit të kërkuar." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Pajisja është e çmontuar tashmë." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Pajisja s’është e montuar." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "S’i lejohet të përdorë mundësinë e kërkuar." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Pajisja është montuar nga tjetër përdorues." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Hapësirë e ulët në pjesë sistemi: {percent_used}% të përdorura, {free_space} " "të lira." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Hapësirë disku e pamjaftueshme" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Shumë afër dështimi disku" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6710,39 +6655,39 @@ msgstr "" "Disku {id} po raporton se ka gjasa të dështojë tani afër. Kopjoni çfarëdo të " "dhënash që mundeni ende dhe zëvendësoni diskun." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Listë e pavlefshme emrash." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Drejtoria s’ekziston." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Shtegu s’është drejtori." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Drejtoria s’është e lexueshme nga përdoruesi." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Drejtoria s’është e shkrueshme nga përdoruesi." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Drejtori" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Nëndrejtori (opsionale)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Drejtori tjetër (jepeni më poshtë)" @@ -6779,7 +6724,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Zgjero Pjesën Rrënjë" @@ -6802,30 +6747,30 @@ msgstr "" "veprimi, në pjesën tuaj rrënjë do të ketë %(expandable_root_size)s hapësirë " "shtesë të lirë." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Gabim në zgjerim pjese: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Pjesa u zgjerua me sukses." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} mund të hiqet pa rrezik." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Pajisja mund të hiqet pa rrezik." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Gabim në nxjerrje pajisjeje: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6837,7 +6782,7 @@ msgstr "" "ndryshimi, ose fshirja e kartelave në një pajisje do të përsëritet vetvetiu " "në krejt pajisjet e tjera që xhirojnë gjithashtu Syncthing-un." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6856,20 +6801,20 @@ msgstr "" "Ndërfaqja web te {box_name} është e përdorshme vetëm nga përdorues që i " "përkasin grupit “përgjegjës”, ose atij “syncthing-access”." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Administroni aplikacionin Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Njëkohësim Kartelash" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6883,48 +6828,49 @@ msgstr "" "përdorni Shfletuesin Tor." -#: plinth/modules/tor/__init__.py:34 -#, fuzzy, python-brace-format -#| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." +#: plinth/modules/tor/__init__.py:30 +#, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." -msgstr "Një portë SOCKS Tor-i në %(box_name)s tuaj gjendet në portën TCP 9050." +msgstr "" +"Një portë SOCKS Tor-i për rrjete të brendshëm në {box_name} tuaj gjendet në " +"portën TCP 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Shërbim Onion Tor" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Ndërmjetës SOCKS Tor" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Rele Ure Tor" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Portë releje Tor e gatshme" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "U regjistruar transport Obfs3" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "U regjistruar transport Obfs3" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "URL hyrjesh {url} në tcp{kind} përmes Tor-i" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Ripohoni përdorim Tor-i te {url} në tcp{kind}" @@ -7046,17 +6992,14 @@ msgstr "Shërbim Onion" msgid "Ports" msgstr "Porta" -#: plinth/modules/tor/views.py:55 -#, fuzzy -#| msgid "An error occurred during configuration." +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" -msgstr "Ndodhi një gabim gjatë formësimit." +msgstr "Po përditësohet formësimi" -#: plinth/modules/tor/views.py:72 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/modules/tor/views.py:70 +#, python-brace-format msgid "Error configuring app: {error}" -msgstr "Gabim në instalimin e aplikacionit: {error}" +msgstr "Gabim në formësimin e aplikacionit: {error}" #: plinth/modules/transmission/__init__.py:23 msgid "Transmission is a BitTorrent client with a web interface." @@ -7082,16 +7025,13 @@ msgid "" msgstr "" #: plinth/modules/transmission/__init__.py:32 -#, fuzzy, python-brace-format -#| msgid "" -#| "It can be accessed by any user on {box_name} " -#| "belonging to the admin group." +#, python-brace-format msgid "" "It can be accessed by any user on {box_name} " "belonging to the bit-torrent group." msgstr "" "Mund të përdoret nga cilido përdorues në " -"{box_name} që është pjesë e grupit të përgjegjësve." +"{box_name} që është pjesë e grupit bit-torrent." #: plinth/modules/transmission/__init__.py:36 #, python-brace-format @@ -7106,13 +7046,15 @@ msgid "" "After a download has completed, you can also access your files using the Sharing app." msgstr "" +"Pasi të jetë plotësuar një shkarkim, te kartelat tuaja mund të hyni edhe " +"duke përdorur aplikacionin Ndarje Me të Tjerë." #: plinth/modules/transmission/__init__.py:66 #: plinth/modules/transmission/manifest.py:6 msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7122,19 +7064,17 @@ msgstr "" "i konceptuar të lejojë lexim lajmesh prej çfarëdo vendndodhjeje, ndërkohë që " "duket si një aplikacion desktop, aq afër kësaj sa mundet." -#: plinth/modules/ttrss/__init__.py:27 -#, fuzzy, python-brace-format -#| msgid "" -#| "When enabled, Tiny Tiny RSS can be accessed by any user with a {box_name} login." +#: plinth/modules/ttrss/__init__.py:24 +#, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -"Kur aktivizohet, Tiny Tiny RSS mund të përdoret nga cilido përdorues me kredenciale hyrjeje në {box_name}." +"Kur aktivizohet, Tiny Tiny RSS mund të përdoret nga cilido përdorues pjesëtar i grupit të leximit të " +"prurjeve." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7143,11 +7083,11 @@ msgstr "" "dekstop, përdorni URL /tt-rss-app për t’u " "lidhur." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Lexues Prurjesh Lajmesh" @@ -7155,13 +7095,13 @@ msgstr "Lexues Prurjesh Lajmesh" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Kontrolloni dhe aplikoni përditësimet më të reja software-i dhe sigurie." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7174,22 +7114,22 @@ msgstr "" "rinisja e sistemit shihet si e domosdoshme, bëhet automatikisht më 02:00, " "duke bërë që krejt aplikacionet të jenë jashtë funksionimi për ca çaste." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Përditësim Software-i" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox-i u Përditësua" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "S’u fillua dot përditësim shpërndarjeje" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7200,11 +7140,11 @@ msgstr "" "Përditësimi i shpërndarjes do të riprovohet pas 24 orësh, nëse kjo është " "aktivizuar." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Përditësimi i shpërndarjes filloi" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7368,69 +7308,61 @@ msgid "Show recent update logs" msgstr "Shfaq regjistra të freskët përditësimesh" #: plinth/modules/upgrades/templates/upgrades_configure.html:138 -#, fuzzy -#| msgid "Distribution upgrade enabled" msgid "Test Distribution Upgrade" -msgstr "Me përmirësim shpërndarjeje të aktivizuar" +msgstr "" #: plinth/modules/upgrades/templates/upgrades_configure.html:140 msgid "" "This will attempt to upgrade the system from stable to testing. It " "is meant only for development use." msgstr "" +"Kjo do të rreket të përmirësojë sistemin nga versioni i qëndrueshëm në " +"versionin testim. Është menduar vetëm për përdorim zhvillimi të " +"platformës." #: plinth/modules/upgrades/templates/upgrades_configure.html:150 -#, fuzzy -#| msgid "Distribution upgrade enabled" msgid "Test distribution upgrade now" -msgstr "Me përmirësim shpërndarjeje të aktivizuar" +msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" "Gabim teksa formësohej <em>unattended-upgrades</em>: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "U aktivizuan përmirësime të automatizuara" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Përmirësimet e vetvetishme janë çaktivizuar" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Me përmirësim shpërndarjeje të aktivizuar" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Me përmirësim shpërndarjeje të çaktivizuar" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Procesi i përmirësimit filloi." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Nisja e përmirësimi dështoi." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Përditësime të shpeshta veçorish të aktivizuara." -#: plinth/modules/upgrades/views.py:223 -#, fuzzy -#| msgid "Distribution upgrade enabled" +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." -msgstr "Me përmirësim shpërndarjeje të aktivizuar" +msgstr "Po fillohet provë përmirësimi shpërndarjeje." -#: plinth/modules/users/__init__.py:29 -#, fuzzy -#| msgid "" -#| "Create and managed user accounts. These accounts serve as centralized " -#| "authentication mechanism for most apps. Some apps further require a user " -#| "account to be part of a group to authorize the user to access the app." +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7441,7 +7373,7 @@ msgstr "" "aplikacione kërkojnë doemos një llogari përdoruesi, për të qenë pjesë e një " "grupi që autorizon përdoruesin të përdorë aplikacionin." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7453,15 +7385,15 @@ msgstr "" "vetëm përdoruesit e grupit përgjegjës mund të ndryshojnë " "aplikacionet, apo rregullimet e sistemit." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Përdorues dhe Grupe" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Hyrje te krejt shërbimet dhe rregullime të sistemit" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Kontrolloni zërin LDAP \"{search_item}\"" @@ -7481,11 +7413,11 @@ msgstr "" "E domosdoshme. 150 ose më pak shenja. Vetëm shkronja anglishteje, shifra, " "dhe @/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Fjalëkalim Autorizimi" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7493,11 +7425,11 @@ msgstr "" "Jepni fjalëkalimin për përdoruesin “{user}”, që të autorizoni ndryshime " "llogarie." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Fjalëkalim i pavlefshëm." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7512,12 +7444,12 @@ msgstr "" "në krejt shërbimet. Munden edhe të hyjnë në sistem përmes SSH-së dhe të kenë " "privilegje administrative (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "S’u arrit të krijohej përdorues LDAP: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "S’u arrit të shtohej përdorues i ri te grupi {group}: {error}" @@ -7537,41 +7469,41 @@ msgstr "" "një për rresht. Rreshta të zbrazët dhe rreshta që fillojnë me # do të " "shpërfillen." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Riemërtimi i përdoruesit LDAP dështoi." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "S’u arrit të hiqej përdorues nga grupi." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "S’u arrit të shtohej përdorues te grup." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "S’arrihet të ujdisen kyçe SSH." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "S’u arrit të ndryshohej gjendje përdoruesi." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Ndryshimi i fjalëkalimit për përdorues LDAP dështoi." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "S’u arrit të shtohej përdorues i ri te grupi i përgjegjësve: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "S’u arrit të kufizohej hyrja në konsol: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Llogaria e përdoruesit u krijua, tani jeni i futur në llogari" @@ -7588,12 +7520,12 @@ msgstr "Ruaje Fjalëkalimin" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Krijoni Përdorues" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Fshi Përdorues" @@ -7635,13 +7567,19 @@ msgid "The following administrator accounts exist in the system." msgstr "Në sistem ekzistojnë llogaritë vijuese përgjegjësish." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Fshijini këto llogari që nga rreshti i urdhrave dhe rifreskoni faqen, që të " "krijohet një llogari e cila të jetë e përdorushme me %(box_name)s. Te " @@ -7650,7 +7588,7 @@ msgstr "" "përdorshme me %(box_name)s, anashkalojeni këtë hap." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Përdorues" @@ -7683,34 +7621,34 @@ msgstr "" msgid "Save Changes" msgstr "Ruaji Ndryshimet" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Përdoruesi %(username)s u krijua." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Përdoruesi %(username)s u përditësua." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Përpunoni Përdorues" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Përdoruesi {user} u fshi." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Fshirja e përdoruesi LDAP dështoi." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Ndryshoni Fjalëkalimin" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Fjalëkalimi u ndryshua me sukses." @@ -8048,7 +7986,7 @@ msgstr "Fshije Lidhjen me Shërbyesin" msgid "Server deleted." msgstr "Shërbyesi u fshi." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -8062,7 +8000,7 @@ msgstr "" "zgjidhet përmes përdorimit të temave. Ndërfaqja e administrimit dhe faqet " "web të prodhuara janë të përshtatshme për pajisje celulare." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -8075,7 +8013,7 @@ msgstr "" "{box_name} me emrin e saktë të përkatësisë. Aktivizoni permalidhje te " "ndërfaqja e përgjegjësit, për URL më të mira për te faqet dhe postimet tuaja." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8086,7 +8024,7 @@ msgstr "" "\">faqen e përgjegjësit, që të mund të përdorni ndërfaqen e përgjegjësit " "në të ardhmen." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8097,12 +8035,12 @@ msgstr "" "ose tema shtesë mund të instalohet dhe përmirësohen duke e marrë ju përsipër " "rrezikun." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Sajt dhe Blog" @@ -8119,7 +8057,7 @@ msgstr "" "sajtin ose blogun WordPress. Aktivizojeni vetëm pasi të jetë kryer ujdisja " "fillestare e WordPress-it." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8141,7 +8079,7 @@ msgstr "" "pamjet hartë dhe kalendar. Foto individuale mund të ndahen me të tjerë duke " "dërguar një lidhje të drejtpërdrejtë." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8152,11 +8090,11 @@ msgstr "" "Zoph. Për përdorues të tjerë, llogaritë mund të krijohen si në {box_name}, " "ashtu edhe në Zoph, me të njëjtin emër përdoruesi." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Sistemues Fotografish" @@ -8195,134 +8133,109 @@ msgid "Generic" msgstr "Elementar" #: plinth/operation.py:116 -#, fuzzy, python-brace-format -#| msgid "Error setting hostname: {exception}" +#, python-brace-format msgid "Error: {name}: {exception_message}" -msgstr "Gabim në caktim strehëemri: {exception}" +msgstr "Gabim: {name}: {exception_message}" #: plinth/operation.py:119 #, python-brace-format msgid "Waiting to start: {name}" -msgstr "" +msgstr "Po pritet të fillohet: {name}" #: plinth/operation.py:125 #, python-brace-format msgid "Finished: {name}" -msgstr "" +msgstr "Përfundoi: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" -msgstr "" +msgstr "Paketa {expression} s’është e gatshme për instalim" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" "Paketa {package_name} gjendet nën versionin më të ri ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Gabim Gjatë Kopjeruajtjes" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "po instalohet" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "po shkarkohet" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "ndryshim media" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "kartelë formësimi: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" -msgstr "" +msgstr "Mbaroi koha teksa pritej për përgjegjës paketash" -#: plinth/setup.py:40 -#, fuzzy -#| msgid "Install Apps" +#: plinth/setup.py:41 msgid "Installing app" -msgstr "Instaloni Aplikacione" +msgstr "Po instalohet aplikacioni" -#: plinth/setup.py:42 -#, fuzzy -#| msgid "Updating..." +#: plinth/setup.py:43 msgid "Updating app" -msgstr "Po përditësohet…" +msgstr "Po përditësohet aplikacioni" -#: plinth/setup.py:68 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {string} {details}" +#: plinth/setup.py:69 +#, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Gabim në instalimin e aplikacionit: {string} {details}" -#: plinth/setup.py:72 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {string} {details}" +#: plinth/setup.py:73 +#, python-brace-format msgid "Error updating app: {string} {details}" -msgstr "Gabim në instalimin e aplikacionit: {string} {details}" +msgstr "Gabim në përditësimin e aplikacionit: {string} {details}" -#: plinth/setup.py:78 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/setup.py:79 +#, python-brace-format msgid "Error installing app: {error}" msgstr "Gabim në instalimin e aplikacionit: {error}" -#: plinth/setup.py:81 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/setup.py:82 +#, python-brace-format msgid "Error updating app: {error}" -msgstr "Gabim në instalimin e aplikacionit: {error}" +msgstr "Gabim në përditësimin e aplikacionit: {error}" -#: plinth/setup.py:85 -#, fuzzy -#| msgid "Application installed." +#: plinth/setup.py:86 msgid "App installed." msgstr "Aplikacioni u instalua." -#: plinth/setup.py:87 -#, fuzzy -#| msgid "Last update" +#: plinth/setup.py:88 msgid "App updated" -msgstr "Përditësimi i fundit më" +msgstr "Aplikacioni u përditësua" -#: plinth/setup.py:104 -#, fuzzy -#| msgid "Install Apps" +#: plinth/setup.py:105 msgid "Uninstalling app" -msgstr "Instaloni Aplikacione" +msgstr "Po çinstalohet aplikacion" -#: plinth/setup.py:122 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {string} {details}" +#: plinth/setup.py:123 +#, python-brace-format msgid "Error uninstalling app: {string} {details}" -msgstr "Gabim në instalimin e aplikacionit: {string} {details}" +msgstr "Gabim në çinstalimin e aplikacionit: {string} {details}" -#: plinth/setup.py:128 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/setup.py:129 +#, python-brace-format msgid "Error uninstalling app: {error}" -msgstr "Gabim në instalimin e aplikacionit: {error}" +msgstr "Gabim në çinstalimin e aplikacionit: {error}" -#: plinth/setup.py:131 -#, fuzzy -#| msgid "Application installed." +#: plinth/setup.py:132 msgid "App uninstalled." -msgstr "Aplikacioni u instalua." +msgstr "Aplikacioni u çinstalua." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" -msgstr "" +msgstr "Po përditësohet paketa aplikacioni" #: plinth/templates/403.html:10 msgid "403 Forbidden" @@ -8379,53 +8292,54 @@ msgstr "Instalim" msgid "Service %(service_name)s is not running." msgstr "Shërbimi %(service_name)s s’po xhiron." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Funksione bazë dhe ndërfaqe web për %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Kreu" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Kreu" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Aplikacione" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Aplikacione" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Sistem" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Sistem" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Ndryshoni fjalëkalimin" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Fike" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Dil" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Përzgjidhni gjuhën" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Hyni" @@ -8548,7 +8462,7 @@ msgstr "FreedomBox Foundation" #: plinth/templates/index.html:146 msgid "Forum" -msgstr "" +msgstr "Forum" #: plinth/templates/index.html:151 msgid "IRC Chatroom" @@ -8625,10 +8539,8 @@ msgstr "" "%(service_name)s:" #: plinth/templates/port-forwarding-info.html:37 -#, fuzzy -#| msgid "Service Type" msgid "Service Name" -msgstr "Lloj Shërbimi" +msgstr "Emër Shërbimi" #: plinth/templates/port-forwarding-info.html:38 msgid "Protocol" @@ -8683,26 +8595,25 @@ msgstr "Përditësoje" #: plinth/templates/toolbar.html:39 plinth/templates/toolbar.html:40 #: plinth/templates/uninstall.html:36 -#, fuzzy -#| msgid "Install" msgid "Uninstall" -msgstr "Instaloje" +msgstr "Çinstaloje" #: plinth/templates/uninstall.html:11 -#, fuzzy, python-format -#| msgid "Edit User %(username)s" +#, python-format msgid "Uninstall App %(app_name)s?" -msgstr "Përpunoni Përdoruesin %(username)s" +msgstr "Të çinstalohet Aplikacioni %(app_name)s?" #: plinth/templates/uninstall.html:17 msgid "Uninstalling an app is an exprimental feature." -msgstr "" +msgstr "Çinstalimi i një aplikacioni është një veçori eksperimentale." #: plinth/templates/uninstall.html:23 msgid "" "All app data and configuration will be permanently lost. App may be " "installed freshly again." msgstr "" +"Krejt të dhënat dhe formësimi i aplikacionit do të humbin përgjithnjë. " +"Aplikacioni mund të instalohet sërish nga e para." #: plinth/views.py:221 msgid "Setting unchanged" @@ -8711,12 +8622,81 @@ msgstr "Rregullim i pandryshuar" #: plinth/views.py:401 #, python-brace-format msgid "before uninstall of {app_id}" -msgstr "" +msgstr "para çinstalimit të {app_id}" #: plinth/web_framework.py:114 msgid "Gujarati" msgstr "Gujaratase" +#~ msgid "Enable DNSSEC" +#~ msgstr "Aktivizo DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Aktivizo Zgjerime Sigurie Sistemi Emrash Shërbyesish" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Demoni i firewall-it s’është vënën në punë. Ju lutemi, vëreni në punë. " +#~ "Firewall-i vjen i aktivizuar, si parazgjedhje, në %(box_name)s. Në " +#~ "çfarëdo sistemi me bazë Debian (si edhe %(box_name)s) mund ta vini në " +#~ "punë duke përdorur urdhrin “service firewalld start”, ose, në rast të një " +#~ "sistemi me systemd, me “systemctl start firewalld”." + +#~ msgid "Migrate to ECC" +#~ msgstr "Migroje në ECC" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Instalimi juaj OpenVPN aktualisht përdor RSA. Kalimi nën Kriptografinë " +#~ "moderne Kurbash Eliptike përmirëson shpejtësinë e vendosjes së një " +#~ "lidhjeje dhe sigurinë. Ky veprim është i pakthyeshëm. Në shumicën e " +#~ "kompjuterave njëskedësh ha vetëm pak minuta." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Krejt instalimet e reja të OpenVPN në %(box_name)s do të përdorin KKE " +#~ "(ECC), si parazgjedhje. Rekomandojmë migrim sa më shpejt të jetë e mundur." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Kujdes: Profile klientësh ekzistues do të bëhen të pavlefshme nga " +#~ "ky veprim. Krejt përdoruesit OpenVPN te %(box_name)s duhet të shkarkojnë " +#~ "profilet e tyre të rinj. Për t’u lidhur me këtë shërbyes, duhen përdorur " +#~ "klientë OpenVPN të përputhshëm me KKE (ECC)." + +#~ msgid "Migrate" +#~ msgstr "Migroje" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "Mirëfilltësimi SSH me fjalëkalim u çaktivizua." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Mirëfilltësimi SSH me fjalëkalim u aktivizua." + +#~ msgid "Error running apt-get" +#~ msgstr "Gabim në xhirimin e urdhrit apt-get" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Funksione bazë dhe ndërfaqe web për %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Lidhje Rrjeti" diff --git a/plinth/locale/sr/LC_MESSAGES/django.po b/plinth/locale/sr/LC_MESSAGES/django.po index 0b396a9a7..d40ea111c 100644 --- a/plinth/locale/sr/LC_MESSAGES/django.po +++ b/plinth/locale/sr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:20+0000\n" "Last-Translator: ikmaak \n" "Language-Team: Serbian calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1095,22 +1088,22 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 #, fuzzy #| msgid "Archive created." msgid "Library created." msgstr "Arhiva kreirana." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1153,24 +1146,24 @@ msgstr "Kokpit" msgid "Server Administration" msgstr "Administracija Servera" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1266,47 +1259,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1314,7 +1307,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1544,11 +1537,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1660,7 +1653,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1721,13 +1714,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1851,14 +1844,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1866,7 +1859,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1876,13 +1869,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2011,7 +2004,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2019,7 +2012,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -2039,61 +2032,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2139,7 +2123,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2150,73 +2134,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2260,19 +2244,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2565,7 +2549,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2573,31 +2557,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Proxy" @@ -2634,14 +2618,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2650,15 +2634,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2712,41 +2696,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2754,11 +2738,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2804,7 +2788,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2822,7 +2806,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2832,7 +2816,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2840,15 +2824,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2911,41 +2895,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2955,14 +2939,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3043,7 +3027,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3051,7 +3035,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3060,18 +3044,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3142,39 +3126,39 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain Name Server" msgid "Domain name updated" msgstr "Domain Name Server" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain Name Server" msgid "Site name updated" msgstr "Domain Name Server" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3183,11 +3167,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3232,7 +3216,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3393,19 +3377,19 @@ msgstr "" msgid "Services" msgstr "Služi" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3751,7 +3735,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3856,7 +3840,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3872,7 +3856,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3885,7 +3869,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4429,7 +4413,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4440,20 +4424,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4463,61 +4447,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4526,33 +4478,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4561,87 +4513,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4675,29 +4627,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4739,8 +4691,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4782,6 +4734,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4813,7 +4796,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4824,7 +4807,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4844,7 +4827,7 @@ msgstr "" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4854,19 +4837,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4927,7 +4910,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4999,7 +4982,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5012,13 +4995,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5027,31 +5010,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5129,17 +5112,17 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 #, fuzzy #| msgid "FreedomBox" msgid "FreedomBox OS disk" msgstr "KutijaSlobode" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5165,51 +5148,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5362,14 +5345,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5378,97 +5361,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5505,26 +5488,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5532,14 +5515,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5633,7 +5616,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5681,59 +5664,59 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 #, fuzzy #| msgid "Archive created." msgid "manually created" msgstr "Arhiva kreirana." -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5741,7 +5724,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5774,14 +5757,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5794,7 +5769,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5802,143 +5777,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5972,7 +5947,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5990,30 +5965,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6021,7 +5996,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6033,20 +6008,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6055,47 +6030,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6193,13 +6168,13 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "Configuration updated" msgid "Updating configuration" msgstr "Konfiguracija sačuvana" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6257,14 +6232,14 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "It can be accessed by any user on {box_name} " @@ -6276,17 +6251,17 @@ msgstr "" "Pristup moguć korisnik na {box_name} koja " "pripada admin grupi." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6294,12 +6269,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6307,33 +6282,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6481,51 +6456,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6533,15 +6508,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6559,21 +6534,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6582,12 +6557,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6603,41 +6578,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6654,12 +6629,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6697,17 +6672,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6738,34 +6713,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7074,7 +7049,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7083,7 +7058,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7092,26 +7067,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7125,7 +7100,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7138,7 +7113,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7146,11 +7121,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7199,110 +7174,104 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Existing Backups" -msgid "Error running apt-get" -msgstr "Postojeće rezervne kopije" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Greška prilikom instaliranja aplikacije: {string}{details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Greška prilikom instaliranja aplikacije: {string}{details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Greška prilikom instaliranja aplikacije: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Greška prilikom instaliranja aplikacije: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Aplikacija instalirana." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "Greška prilikom instaliranja aplikacije: {error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Greška prilikom instaliranja aplikacije: {string}{details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Greška prilikom instaliranja aplikacije: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Aplikacija instalirana." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7353,53 +7322,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -7663,6 +7633,17 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "Aktiviraj DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Aktiviraj Domain Name System Security Ekstenziju" + +#, fuzzy +#~| msgid "Existing Backups" +#~ msgid "Error running apt-get" +#~ msgstr "Postojeće rezervne kopije" + #~ msgid "" #~ "Cockpit requires that you access it through a domain name. It will not " #~ "work when accessed using an IP address as part of the URL." diff --git a/plinth/locale/sv/LC_MESSAGES/django.po b/plinth/locale/sv/LC_MESSAGES/django.po index 12d9d2444..8d28c0321 100644 --- a/plinth/locale/sv/LC_MESSAGES/django.po +++ b/plinth/locale/sv/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" -"PO-Revision-Date: 2022-09-26 14:19+0000\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" +"PO-Revision-Date: 2022-10-03 14:15+0000\n" "Last-Translator: Michael Breidenbach \n" "Language-Team: Swedish \n" @@ -61,10 +61,8 @@ msgid "Restoring from the backup will restore app data." msgstr "Om du återställer från säkerhetskopian återställs appdata." #: plinth/forms.py:39 -#, fuzzy -#| msgid "Repository not found" msgid "Repository to backup to" -msgstr "Databasen hittades inte" +msgstr "Repository att säkerhetskopiera till" #: plinth/forms.py:56 msgid "Select a domain name to be used with this application" @@ -117,17 +115,17 @@ msgstr "Webbserver" msgid "{box_name} Web Interface (Plinth)" msgstr "{box_name} Webbgränssnitt (Plinth)" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "Anslut till adress {url} på tcp{kind}" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "Anslut till adress {url}" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -144,24 +142,24 @@ msgstr "" "nätverk. Du kan låta den vara inaktiverad för att förbättra din säkerhet, " "särskilt om du ansluter till ett osäkert lokalt nätverk." -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "Identifiera tjänster" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "Lokalt nätverksdomän" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "Säkerhetskopior gör det möjligt att skapa och hantera säkerhetsarkiv." -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "Säkerhetskopiering" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." @@ -169,18 +167,18 @@ msgstr "" "Aktivera ett automatiskt reservschema för datasäkerhet. Föredra en krypterad " "plats för fjärrbackup eller en extra ansluten disk." -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "Aktivera ett schema för säkerhetskopiering" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "Gå till {app_name}" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " @@ -189,7 +187,7 @@ msgstr "" "En schemalagd säkerhetskopiering misslyckades. Tidigare {error_count} försök " "för säkerhetskopiering lyckades inte. Det senaste felet är: {error_message}" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "Fel under säkerhetskopiering" @@ -334,7 +332,7 @@ msgstr "" msgid "Key in Repository" msgstr "Key i databasen" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "Ingen" @@ -402,7 +400,7 @@ msgstr "Fjärrbackup respository finns redan." msgid "Select verified SSH public key" msgstr "Välj verifierad Offentlig SSH-nyckel" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." @@ -410,31 +408,31 @@ msgstr "" "Anslutningen nekad-Kontrollera att du har angett rätt " "autentiseringsuppgifter och servern körs." -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "Anslutningen nekades" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "Databasen hittades inte" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "Felaktig krypteringslösenfras" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "SSH-åtkomst nekad" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "Respositorysökvägen är varken tom eller en befintlig säkerhetskopia." -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "Befintlig respository är inte krypterad." -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "{box_name} lagring" @@ -493,7 +491,7 @@ msgid "Create Location" msgstr "Skapa plats" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "Skapa respository" @@ -737,7 +735,7 @@ msgstr "Avmontering misslyckas!" msgid "Mounting failed" msgstr "Avmontering misslyckades" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -749,7 +747,7 @@ msgstr "" "ljud, video och PDF-dokument kan förhandsgranskas i webbläsaren. Delade " "filer kan ställas in för att löpa ut efter en tidsperiod." -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -761,7 +759,7 @@ msgstr "" "har skapat ett lösenord kan du dela det med de användare som ska ha " "tillhörande behörigheter." -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -773,39 +771,39 @@ msgstr "" "återkalla åtkomst för en enda person eller grupp, genom att ta bort deras " "lösenord från listan." -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "Läs en fil om en webblänk till filen är tillgänglig" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "Skapa eller ladda upp filer" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "Lista alla filer och deras webblänkar" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "Ta bort filer" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "Administrera filer: låsa/låsa upp filer" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "Inget, lösenord krävs alltid" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "Lista och läsa alla filer" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "bepasty" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "Fil & Snippet Sharing" @@ -820,7 +818,7 @@ msgstr "" #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "Behörigheter" @@ -857,35 +855,35 @@ msgstr "Inga lösenord har för närvarande konfigurerats." #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "Lösenord" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "Admin" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "Redigerare" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "Visare" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "Läsa" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "Skapa" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "Lista" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -897,35 +895,35 @@ msgstr "Lista" msgid "Delete" msgstr "Ta bort" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "Admin" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "Konfiguration uppdaterad." -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "Ett fel inträffade under konfiguration." -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "Lösenord tillagt." -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "Lägg till lösenord" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "Lösenord raderat." -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." @@ -933,7 +931,7 @@ msgstr "" "Med BIND kan du publicera din Domain Name System (DNS) -information på " "Internet och lösa DNS sökfrågor för dina användarenheter i ditt nätverk." -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -944,33 +942,25 @@ msgstr "" "andra maskiner i det lokala nätverket. Det är också oförenligt med att dela " "Internet-anslutning från {box_name}." -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "BIND" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "Domän Namn Server" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "Vidarebefordrare" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" "En lista med DNS-servrar, separerade med mellanslag, till vilka " "förfrågningar kommer att vidarebefordras" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "Aktivera DNSSEC" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "Aktivera Domain Name System Security Extensions" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "Betjäna domäner" @@ -1002,19 +992,20 @@ msgstr "IP-adresser" msgid "Refresh IP address and domains" msgstr "Uppdatera IP-adress och domäner" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "Konfiguration uppdaterad" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -1024,7 +1015,7 @@ msgstr "" "calibre server ger online tillgång till din e-bok samling. Du kan lagra dina " "e-böcker på din {box_name}, läsa dem online eller från någon av dina enheter." -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -1039,7 +1030,7 @@ msgstr "" "lästa plats, bokmärken och markerad text. Innehållsdistribution med OPDS " "stöds för närvarande inte." -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1047,23 +1038,23 @@ msgstr "" "Endast användare som tillhör calibre -gruppen kan komma åt appen. " "Alla användare med åtkomst kan använda alla bibliotek." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Använd calibre e-bokbibliotek" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-bok Bibliotek" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Det nya bibliotekets namn" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1071,7 +1062,7 @@ msgstr "" "Endast bokstäver i det engelska alfabetet, siffror och tecken _ . och - utan " "mellanslag eller specialtecken. Exempel: My_Library_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Ett bibliotek med detta namn finns redan." @@ -1119,20 +1110,20 @@ msgstr "Gå till biblioteket %(library)s" msgid "Delete library %(library)s" msgstr "Ta bort bibliotek %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Bibliotek skapat." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Ett fel uppstod när biblioteket skulle skapas." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} borttagen." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Kunde inte ta bort {name}: {error}" @@ -1180,7 +1171,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Server administrering" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1188,18 +1179,18 @@ msgstr "" "Här kan du ställa in några allmänna konfigurationsalternativ som värdnamn, " "domännamn, webserver, hemsida etc." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Allmän Konfiguration" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Konfigurera" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1289,10 +1280,8 @@ msgid "Show apps and features that require more technical knowledge." msgstr "Visa appar och funktioner som kräver mer teknisk kunskap." #: plinth/modules/config/forms.py:104 -#, fuzzy -#| msgid "System Monitoring" msgid "System-wide logging" -msgstr "Systemövervakning" +msgstr "Systemomfattande loggning" #: plinth/modules/config/forms.py:105 msgid "Disable logging, for privacy" @@ -1314,47 +1303,47 @@ msgstr "" "Loggar innehåller information om vem som har åtkomst till systemet och " "felsökningsinformation från olika tjänster" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Fel inställning av värdnamn: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Värdnamn inställt" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Fel inställning av domännamn: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Domännamn inställt" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Fel vid inställning av webbserverns hemsida: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Webbserverns hemsida är inställt" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Fel vid ändring av avancerat läge: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Visar avancerade appar och funktioner" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Dölja avancerade appar och funktioner" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1366,7 +1355,7 @@ msgstr "" "WebRTC, SIP och andra kommunikationsservrar kan använda den för att upprätta " "ett samtal mellan parter som annars inte kan ansluta till varandra." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse eller ejabberd måste " "konfigureras med de uppgifter som tillhandahålls här." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP-hjälpare" @@ -1439,13 +1428,13 @@ msgstr "Fel i inställning av tidszon: {exception}" msgid "Time zone set" msgstr "Tidszon inställd" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "" "Deluge är en BitTorrentklient som inkluderar ett Webbaserat " "användargränssnitt." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1453,16 +1442,16 @@ msgstr "" "Standardlösenordet är \"deluge\", men du bör logga in och ändra det " "omedelbart efter att du har aktiverat den här tjänsten." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Ladda ner filer med BitTorrent-applikationer" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent Webbklient" @@ -1588,7 +1577,7 @@ msgstr "Resultat" msgid "Diagnostic Test" msgstr "Diagnostiktest" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1599,7 +1588,7 @@ msgstr "" "kan det vara svårt för andra att hitta dig på nätet. Detta förhindrar andra " "att nå de tjänster som tillhandahålls av denna {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1616,7 +1605,7 @@ msgstr "" "servern ditt DNS-namn till din nya IP, och om någon från Internet ber om " "ditt DNS-namn, kommer hen att få din aktuella IP som svar." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1629,11 +1618,11 @@ msgstr "" "baserade tjänster på freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Klient för Dynamisk DNS" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Dynamiskt Domännamn" @@ -1761,7 +1750,7 @@ msgstr "Detta fält krävs." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1816,7 +1805,7 @@ msgstr "Servern vägrade anslutning" msgid "Already up-to-date" msgstr "Redan uppdaterad" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1824,7 +1813,7 @@ msgstr "" "XMPP är en öppen och standardiserad kommunikationsprotokoll. Här kan du köra " "din XMPP-server (kallad ejabberd)." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client användare med en {box_name} inloggning." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn eller konfigurera en extern server." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabbert" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Chat-Server" #: plinth/modules/ejabberd/forms.py:19 -#, fuzzy -#| msgid "Domain Names" msgid "Domain names" msgstr "Domännamn" @@ -1975,7 +1962,7 @@ msgstr "" "kommer att se ut som användarnamn@%(domainname)s. Du kan ställa in " "din domän på systemet Konfigurera sidan." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1986,7 +1973,7 @@ msgstr "" "postklienter att komma åt din brevlåda med hjälp av IMAP och POP3. Rspamd " "tar hand om skräppost." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1999,7 +1986,7 @@ msgstr "" "begränsningen efter en uttrycklig begäran. Se manualsidan för mer " "information." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2014,7 +2001,7 @@ msgstr "" "alias som \"postmaster\" skapas automatiskt och pekar på den första " "administratörsanvändaren." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2022,7 +2009,7 @@ msgstr "" "Roundcube app ger användarna " "webbgränssnitt för att komma åt e-post." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2152,7 +2139,7 @@ msgstr "Port" msgid "Host/Target/Value" msgstr "Värd/Mål/Värde" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2163,7 +2150,7 @@ msgstr "" "nätverkstrafiken på din {box_name}. Att ha en brandvägg aktiverad och " "korrekt konfigurerad minskar risken för säkerhetshot från Internet." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Brandvägg" @@ -2183,52 +2170,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} ({details}) är inte tillgängligt för externa nätverk" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Brandväggsdemonen körs inte. Vänligen starta den. Brandväggen är aktiverad " -"som standard på %(box_name)s. På ett Debian-baserade system (till exempel " -"%(box_name)s) Du kan starta den med kommandot \"service firewalld start\", " -"alternativt, vid ett system med systemd \"systemctl start firewalld\"." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Service/Port" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Aktiverad" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Inaktiverad" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Tillåtna" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Tillåtna (endast interna)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Tillåtna (endast externa)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Blockerade" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2238,13 +2212,13 @@ msgstr "" "automatiskt i brandväggen och om du inaktiverar en tjänst, så inaktiveras " "den även automatiskt i brandväggen." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Avancerat" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2297,7 +2271,7 @@ msgstr "Starta installationsprogrammet" msgid "Setup Complete" msgstr "Installationen Klar" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2315,7 +2289,7 @@ msgstr "" "Git-klient eller med flera tillgängliga grafiska klienter. Och du kan dela " "din kod med människor runt om i världen." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2323,68 +2297,68 @@ msgstr "" "För att lära dig mer om hur du använder Git besökGit handledning." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Läs-skrivåtkomst till Git-respositories" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Enkelt Git hosting" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Ogiltigt respository URL." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Ogiltigt respository namn." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Namn på en ny databas eller URL för att importera en befintlig databas." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Beskrivning av förvaret" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Tillval, för att visa på Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Förvarets ägarnamn" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Privat respository" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Tillåt endast behöriga användare att komma åt detta respository." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Ett förvar med det här namnet finns redan." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Förvarets namn" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "En alfanumerisk sträng som identifierar ett respository unikt." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Standardgren" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb visar detta som en standardgren." @@ -2428,19 +2402,19 @@ msgstr "Ta bort Git-respository %(name)s" msgid "Delete this repository permanently?" msgstr "Radera detta arkiv permanent?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Respository skapat." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Ett fel uppstod medan skapa ett repository." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Respository redigerad." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Redigera respository" @@ -2621,31 +2595,33 @@ msgid "" "Below is a list of opportunities for contributing to Debian. It has been " "filtered to only show packages that are installed on this system." msgstr "" +"Nedan finns en lista över möjligheter att bidra till Debian. Det har " +"filtrerats för att bara visa paket som är installerade på det här systemet." #: plinth/modules/help/templates/help_contribute.html:59 msgid "Show issues" -msgstr "" +msgstr "Visa problem" #: plinth/modules/help/templates/help_contribute.html:63 msgid "Packages that will be removed from Debian testing" -msgstr "" +msgstr "Paket som kommer att tas bort från Debian testing" #: plinth/modules/help/templates/help_contribute.html:69 #: plinth/modules/help/templates/help_contribute.html:85 msgid "source package:" -msgstr "" +msgstr "källkodspaketet:" #: plinth/modules/help/templates/help_contribute.html:80 msgid "Packages that are not in Debian testing" -msgstr "" +msgstr "Paket som inte finns i Debian testing" #: plinth/modules/help/templates/help_contribute.html:92 msgid "Good first issues for beginners" -msgstr "" +msgstr "Bra första problem för nybörjare" #: plinth/modules/help/templates/help_contribute.html:104 msgid "Issues for which the package maintainer has requested help" -msgstr "" +msgstr "Problem som paketansvarige har begärt hjälp för" #: plinth/modules/help/templates/help_feedback.html:12 #, python-format @@ -2801,7 +2777,7 @@ msgstr "Om {box_name}" msgid "{box_name} Manual" msgstr "{box_name} Manual" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2813,7 +2789,7 @@ msgstr "" "anonymitet genom att skicka krypterad trafik via ett volontärstyrt nätverk " "distribuerat över hela världen." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2821,7 +2797,7 @@ msgstr "" "För att hitta mer information om I2P på deras projekthemsida." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." @@ -2829,19 +2805,19 @@ msgstr "" "Det första besöket i det medföljande webbgränssnittet kommer att initiera " "konfigurationsprocessen." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Hantera I2P appen" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Anonymitetsnätverk" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P proxy" @@ -2886,7 +2862,7 @@ msgstr "" "to-peer-nätverk. Ladda ner filer genom att lägga till torrenter eller skapa " "en ny torrent för att dela en fil." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2896,7 +2872,7 @@ msgstr "" "lightweight pålägg språken, inklusive markdown, och gemensam blogging " "funktionellitet sådan som kommentarerna och RSS feeds." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2909,15 +2885,15 @@ msgstr "" "redigera befindliga. I Användarkonfiguration kan du ändra dessa behörigheter eller lägga till nya användare." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "Ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki och Blogg" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Visa och redigera wiki-applikationer" @@ -2973,41 +2949,41 @@ msgstr "" "Den här åtgärden tar bort alla inlägg, sidor och kommentarer, även " "versionshistorik. Ta bort denna wiki eller blogg permanent?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Skapade wiki {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Kunde inte skapa wiki: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Blogg skapad {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Kunde inte skapa blogg: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} borttagen." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Kunde inte ta bort {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted är en server för Gobby, en kollaborativ textredigerare." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3018,11 +2994,11 @@ msgstr "" ", desktop client och installera det. Starta sedan Gobby och välj " "\"Anslut till server\" och ange ditt {box_name} domännamn." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "Infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby-Server" @@ -3045,16 +3021,16 @@ msgstr "" #: plinth/modules/janus/__init__.py:22 msgid "Janus is a lightweight WebRTC server." -msgstr "" +msgstr "Janus är en lättviktig WebRTC-server." #: plinth/modules/janus/__init__.py:23 msgid "A simple video conference room is included." -msgstr "" +msgstr "Ett enkelt videokonferensrum ingår." #: plinth/modules/janus/__init__.py:25 #, python-brace-format msgid "Coturn is required to use Janus." -msgstr "" +msgstr "Coturn krävs för att använda Janus." #: plinth/modules/janus/__init__.py:41 msgid "Janus" @@ -3062,15 +3038,15 @@ msgstr "Janus" #: plinth/modules/janus/__init__.py:43 msgid "Video Room" -msgstr "" +msgstr "Videorum" #: plinth/modules/janus/manifest.py:7 msgid "Janus Video Room" -msgstr "" +msgstr "Janus videorum" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "JavaScript-licensinformation" @@ -3090,7 +3066,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Chat klient" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3105,7 +3081,7 @@ msgstr "" "domän. Detta sker genom att den bevisar sig vara ägare till en domän för " "Let's Encrypt, en auktoriserad certifikatutfärdare ." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3117,15 +3093,15 @@ msgstr "" "Läs igenom och acceptera Let's Encrypt användaravtal innan du använder denna tjänst." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Låt oss kryptera" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Certifikaterna" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Kan inte testa: Inga domäner är konfigurerade." @@ -3190,7 +3166,7 @@ msgstr "" "Inga domäner har konfigurerats. Konfigurera " "domäner för att kunna få certifikat för dem." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3199,34 +3175,34 @@ msgstr "" "Certifikatet återkallat för domänen {domain}. Det kan ta några ögonblick att " "träda i kraft." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Det gick inte att återkalla certifikatet för domänen {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Certifikat erhållet för domänen {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Det gick inte att erhålla certifikat för domänen {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Certifikatet framgångsrikt återkallat för domänen {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Det gick inte att ta bort certifikatet för domänen {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3243,7 +3219,7 @@ msgstr "" "fungera. Användare på en given Matrix-server kan samtala med användare på " "alla andra Matrix-servrar via federation." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3252,7 +3228,7 @@ msgstr "" "Matrix Synapse behöver en STUN/TURN-server för ljud-/videosamtal. Installera " "Coturn-appen eller konfigurera en extern server." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3357,7 +3333,7 @@ msgstr "" "certifikat. Gå till Let's Encrypt för " "att få en sådan." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3369,7 +3345,7 @@ msgstr "" "kan använda Media att vara värd för en wiki-liknande webbplats, göra " "anteckningar eller samarbeta med vänner på projekt." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3383,7 +3359,7 @@ msgstr "" "fler användarkonton från MediaWiki själv genom att gå till Special: Skapa konto sida." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3391,12 +3367,12 @@ msgstr "" "Alla som har en länk till denna wiki kan läsa den. Endast användare som är " "inloggade kan göra ändringar i innehållet." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Wiki" @@ -3427,14 +3403,12 @@ msgstr "" "\"example.onion\"." #: plinth/modules/mediawiki/forms.py:41 -#, fuzzy -#| msgid "Kite name" msgid "Site Name" -msgstr "Kite namn" +msgstr "Sidnamn" #: plinth/modules/mediawiki/forms.py:42 msgid "Name of the site as displayed throughout the wiki." -msgstr "" +msgstr "Namn på webbplatsen som visas i hela wiki." #: plinth/modules/mediawiki/forms.py:46 msgid "Enable public registrations" @@ -3481,37 +3455,35 @@ msgstr "Lösenord uppdaterad" msgid "Password update failed. Please choose a stronger password" msgstr "Lösenordsuppdateringen misslyckades. Välj ett starkare lösenord" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Offentliga registreringar aktiverade" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Offentliga registreringar avaktiverad" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Privat läge aktiverat" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Privat läge inaktiverat" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Standardskal ändrat" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Domännamnet uppdaterat" -#: plinth/modules/mediawiki/views.py:106 -#, fuzzy -#| msgid "Domain name updated" +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" -msgstr "Domännamnet uppdaterat" +msgstr "Sidnamnet har uppdaterats" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3524,11 +3496,11 @@ msgstr "" "(30000). För att ansluta till servern, en Minetest klient behövs." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Block sandbox" @@ -3578,7 +3550,7 @@ msgstr "Om inaktiverat kan spelare inte dö eller få skador av något slag." msgid "Address" msgstr "Adress" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3689,29 +3661,27 @@ msgstr "" #: plinth/modules/mumble/forms.py:40 msgid "Set a password to join the server" -msgstr "" +msgstr "Ange ett lösenord för att ansluta till servern" #: plinth/modules/mumble/forms.py:42 -#, fuzzy -#| msgid "" -#| "Set a new upload password for Coquelicot. Leave this field blank to keep " -#| "the current password." msgid "" "Set a password that is required to join the server. Leave empty to use the " "current password." msgstr "" -"Ställ in ett nytt överföringslösenord för Coquelicot. Lämna det här fältet " -"tomt för att behålla det aktuella lösenordet." +"Ange ett lösenord som krävs för att ansluta till servern. Lämna det tomt om " +"du vill använda det nuvarande lösenordet." #: plinth/modules/mumble/forms.py:48 msgid "Set the name for the root channel" -msgstr "" +msgstr "Ange namnet på rotkanalen" #: plinth/modules/mumble/forms.py:52 msgid "" "Set the name of the main channel of your mumble server. If the name was " "never changed, the channel is named Root." msgstr "" +"Ange namnet på huvudkanalen på din mumble-server. Om namnet aldrig har " +"ändrats heter kanalen Root." #: plinth/modules/mumble/manifest.py:34 msgid "Mumblefly" @@ -3726,14 +3696,12 @@ msgid "SuperUser password successfully updated." msgstr "SuperUser lösenord har uppdaterats." #: plinth/modules/mumble/views.py:48 -#, fuzzy -#| msgid "Upload password updated" msgid "Join password changed" -msgstr "Ladda upp lösenordet uppdaterat" +msgstr "Lösenordet för anslutning har ändrats" #: plinth/modules/mumble/views.py:53 msgid "Root channel name changed." -msgstr "" +msgstr "Namnet på rotkanalen har ändrats." #: plinth/modules/names/__init__.py:22 #, python-brace-format @@ -3768,7 +3736,7 @@ msgstr "Secure Shell" msgid "Services" msgstr "Tjänster" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3776,7 +3744,7 @@ msgstr "" "Konfigurera nätverksenheter. Anslut till Internet via Ethernet, Wi-Fi eller " "PPPoE. Dela den anslutningen med andra enheter i nätverket." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3784,7 +3752,7 @@ msgstr "" "Enheter som administreras via andra metoder kanske inte är tillgängliga för " "konfiguration här." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Nätverk" @@ -4217,7 +4185,7 @@ msgstr "Redigera anslutning" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Redigera" @@ -4322,7 +4290,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Metod" @@ -4338,7 +4306,7 @@ msgstr "DNS-Server" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Standard" @@ -4351,7 +4319,7 @@ msgid "This connection is not active." msgstr "Den här anslutningen är inte aktiv." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Säkerhet" @@ -4937,7 +4905,7 @@ msgstr "Anslutning {name} borttagen." msgid "Failed to delete connection: Connection not found." msgstr "Det gick inte att ta bort anslutning: Anslutning hittades inte." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4954,20 +4922,20 @@ msgstr "" "tillhandahålls av {box_name}. Du kan också komma åt resten av Internet via " "{box_name} för ökad säkerhet och anonymitet." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Ansluta till VPN-tjänster" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Virtuellt privat nätverk" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4978,58 +4946,21 @@ msgstr "" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "Migrera till ECC" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"Din OpenVPN-installation använder för närvarande RSA. Om du byter till den " -"moderna Elliptic Curve Cryptography förbättrar hastigheten för att upprätta " -"en anslutning och säkerhet. Den här åtgärden är oåterkallelig. Det bör bara " -"ta några minuter på de flesta enda ombord datorer." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"Alla nya installationer av OpenVPN på %(box_name)s kommer att använda ECC " -"som standard. Vi rekommenderar migrering så snart som möjligt." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -" Varning: Befintliga klientprofiler kommer att ogiltigförklaras av " -"den här åtgärden. Alla OpenVPN-användare på %(box_name)s måste hämta sina " -"nya profiler. OpenVPN-klienter som är kompatibla med ECC bör användas för " -"att ansluta till den här servern." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Flytta" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "För att ansluta till %(box_name)s VPN måste du ladda ner en profil och mata " @@ -5038,17 +4969,18 @@ msgstr "" "\" ovan för rekommenderade klienter och instruktioner om hur du konfigurerar " "dem." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" "Profilen är specifik för varje användare av %(box_name)s Håll det hemligt." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Ladda ner min profil" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5061,18 +4993,18 @@ msgstr "" "tjänster inte kan nås från resten av Internet. Detta inkluderar följande " "situationer:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} är bakom en begränsad brandvägg." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} är anslutet till en (trådlös) router som du inte kontrollerar." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5080,7 +5012,7 @@ msgstr "" "Din ISP ger dig inte en extern IP-adress och ger istället Internet " "uppkoppling via NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5088,11 +5020,11 @@ msgstr "" "Din ISP ger dig inte en statisk IP-adress och din IP-adress ändras varje " "gång du ansluter till Internet." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Din ISP begränsar inkommande anslutningar." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5106,23 +5038,23 @@ msgstr "" "pagekite. net . I framtiden kan det vara möjligt att använda din kompis " "{box_name} för detta." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Offentlig Synlighet" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite domän" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Server-domän" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5130,31 +5062,31 @@ msgstr "" "Välj din pagekite-Server. Ange \"pagekite.net\" om du vill använda " "standardservern pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Server Port" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Port på din pagekite Server (standard: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite namn" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Exempel: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Ogiltigt kite-namn" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite hemlighet" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5162,35 +5094,35 @@ msgstr "" "En hemlighet som är associerad med draken eller standard hemligheten för " "ditt konto om ingen hemlighet är inställd på draken." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "Protokollet" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "extern port (frontend)" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "intern port (freedombox)" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Aktivera underdomäner" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Borttagen anpassad tjänst" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Denna tjänst är tillgänglig som standardtjänst." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Lade till anpassad service" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Den här tjänsten finns redan" @@ -5227,33 +5159,33 @@ msgstr "" "de protokoll/port kombinationer som du kan definiera här. Till exempel, " "HTTPS på andra portar än 443 är kända för att orsaka problem." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Webb server (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" "Webbplatsen kommer att finnas tillgänglig på http://" "{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Webb server (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" "Webbplatsen kommer att finnas tillgänglig på https://" "{0} " -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Secure Shell (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5305,8 +5237,8 @@ msgstr "" "För närvarande körs en installation eller uppgradering. Överväg att vänta " "tills den är klar innan du stänger av eller startar om." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Starta om" @@ -5356,6 +5288,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Stäng av nu" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5367,13 +5332,7 @@ msgstr "" "kontrollera åtkomst och ta bort annonser och andra avskyvärda Internet Junk. " #: plinth/modules/privoxy/__init__.py:28 -#, fuzzy, python-brace-format -#| msgid "" -#| "You can use Privoxy by modifying your browser proxy settings to your " -#| "{box_name} hostname (or IP address) with port 8118. While using Privoxy, " -#| "you can see its configuration details and documentation at http://config.privoxy.org/ or http://p.p." +#, python-brace-format msgid "" "You can use Privoxy by modifying your browser proxy settings to your " "{box_name} hostname (or IP address) with port 8118. Only connections from " @@ -5401,7 +5360,7 @@ msgstr "Webbproxy" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Anslut till {url} med proxy {proxy} på TCP {kind}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5418,7 +5377,7 @@ msgstr "" "quassel-klienter från ett skrivbord eller en mobil kan användas för att " "ansluta och koppla från den." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your Desktop och mobila-enheter är tillgängliga." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC-klient" @@ -5442,7 +5401,7 @@ msgstr "IRC-klient" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5457,7 +5416,7 @@ msgstr "" "clients\">stöds klientprogram. Radicale kan nås av alla användare med en " "{box_name} inloggning." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5467,12 +5426,12 @@ msgstr "" "skapandet av nya kalendrar och adressböcker. Det stöder inte att lägga till " "händelser eller kontakter, som måste göras med hjälp av en separat klient." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Kalender och adressbok" @@ -5545,7 +5504,7 @@ msgstr "" "address>) och ditt användarnamn. Om du klickar på sökknappen visas en lista " "över befintliga kalendrar och adressböcker." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Konfiguration av åtkomsträttigheter uppdaterat" @@ -5614,18 +5573,17 @@ msgid "" "RSS-Bridge generates RSS and Atom feeds for websites that do not have one. " "Generated feeds can be consumed by any feed reader." msgstr "" +"RSS-Bridge genererar RSS- och Atom-feeds för webbplatser som inte har en. " +"Genererade feed kan konsumeras av alla feeedläsare." #: plinth/modules/rssbridge/__init__.py:23 -#, fuzzy, python-brace-format -#| msgid "" -#| "When enabled, Tiny Tiny RSS can be accessed by any user belonging to the feed-reader group." +#, python-brace-format msgid "" "When enabled, RSS-Bridge can be accessed by any " "user belonging to the feed-reader group." msgstr "" -"När aktiverat kan Tiny Tiny RSS nås av alla " -"användare som tillhör gruppen feed-reader." +"När RSS-Bridge är aktiverad kan den nås av varje " +"användare som tillhör feed-reader-gruppen." #: plinth/modules/rssbridge/__init__.py:27 #, python-brace-format @@ -5634,21 +5592,24 @@ msgid "" "follow various websites. When adding a feed, enable authentication and use " "your {box_name} credentials." msgstr "" +"Du kan använda RSS-Bridge med Tiny Tiny RSS för " +"att följa olika webbplatser. När du lägger till ett feed aktiverar du " +"autentisering och använder dina {box_name}-autentiseringsuppgifter." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Läsa och prenumerera på nyhetsflöden" #: plinth/modules/rssbridge/__init__.py:48 #: plinth/modules/rssbridge/manifest.py:10 msgid "RSS-Bridge" -msgstr "" +msgstr "RSS-Bridge" #: plinth/modules/rssbridge/__init__.py:49 msgid "RSS Feed Generator" -msgstr "" +msgstr "RSS Feed Generator" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5656,7 +5617,7 @@ msgstr "" "Samba gör det möjligt att dela filer och mappar mellan FreedomBox och andra " "datorer i ditt lokala nätverk." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5669,11 +5630,11 @@ msgstr "" "\\{hostname} (på Windows) eller SMB://{hostname}. local (på Linux och Mac). " "Det finns tre typer av shares som du kan välja mellan: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Öppen delning - tillgänglig för alla i ditt lokala nätverk." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5681,7 +5642,7 @@ msgstr "" "Gruppdelning - endast tillgänglig för FreedomBox-användare som ingår i " "freedombox-delningsgruppen." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5689,15 +5650,15 @@ msgstr "" "Hemdelning - varje användare i gruppen freedombox-share kan ha sitt eget " "privata utrymme." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Tillgång till privata delningar" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Nätverk För Fillagring" @@ -5783,15 +5744,15 @@ msgstr "Resursnamn" msgid "Action" msgstr "Åtgärd" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS-disk" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Öppna Share" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Grupp Share" @@ -5817,7 +5778,7 @@ msgstr "Share resurs inaktiverat." msgid "Error disabling share: {error_message}" msgstr "Fel vid inaktivering av resurs: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5825,7 +5786,7 @@ msgstr "" "Searx är en sekretess-respektera Internet metasökning motor. Det aggregrates " "och visar resultat från flera sökmotorer." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5833,39 +5794,39 @@ msgstr "" "Searx kan användas för att undvika spårning och profilering av sökmotorer. " "Den lagrar inga cookies som standard." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Sök på webben" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Webbsökning" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Säker sökning" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "Välj det standard familjefilter som ska användas för sökresultaten." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Måttlig" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Strikt" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Tillåt offentlig åtkomst" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "Tillåt att det här programmet används av alla som kan nå det." @@ -6045,7 +6006,7 @@ msgstr "Bokmärken" msgid "Shaarlier" msgstr "Shaarli" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6055,7 +6016,7 @@ msgstr "" "Internet-trafik. Det kan användas för att kringgå Internetfiltrering och " "censur." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6068,7 +6029,7 @@ msgstr "" "enheter kan ansluta till denna proxy och deras data kommer att krypteras och " "proxied via Shadowsocks-servern." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6076,41 +6037,41 @@ msgstr "" "Till använda Shadowsocks efter setup, sätta den SOCKS5 genom fullmakt URL i " "din anordning, beter eller applicering till http://freedombox_address: 1080/" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Socks5 proxy" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Rekommenderas" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Server" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Serverns värdnamn eller IP-adress" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Server portnummer" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Lösenord som används för att kryptera data. Måste matcha serverns lösenord." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Krypteringsmetod. Måste matcha inställningen på servern." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6119,15 +6080,15 @@ msgstr "" "Med Sharing kan du dela filer och mappar på din {box_name} över webben med " "utvalda grupper av användare." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Sharing" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Namn på Share-mappen" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6135,27 +6096,27 @@ msgstr "" "En liten alfanumerisk sträng som unikt identifierar en resurs. Exempel: " "Media ." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Sökväg för Share" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Disk Sök väg till en mapp på den här servern som du tänker dela." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Offentlig Share" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Gör filer i den här mappen tillgängliga för alla med länken." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Användargrupper som kan läsa filerna i Share:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6163,11 +6124,11 @@ msgstr "" "Användare av de valda användargrupperna kommer att kunna läsa filerna i " "Share." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Det finns redan en share med det här namnet." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Shares ska antingen vara offentliga eller delas med minst en grupp" @@ -6204,19 +6165,19 @@ msgstr "Share tillagd." msgid "Add Share" msgstr "Lägg till share" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Share redigerad." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Redigera share" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Share borttagen." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6226,7 +6187,7 @@ msgstr "" "Dessa kan användas för att återställa systemet till ett tidigare känt skick " "i händelse av oönskade ändringar i systemet." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6237,7 +6198,7 @@ msgstr "" "även före och efter en programvaruinstallation. Äldre ögonblicksbilder " "kommer att rensas automatiskt enligt inställningarna nedan." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for säkerhetskopior eftersom de bara kan lagras på " "samma partition. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Ögonblicksbilder av lagring" @@ -6351,7 +6312,7 @@ msgstr "Datum" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Ta bort ögonblicksbilder" @@ -6405,57 +6366,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "Återställning till ögonblicksbild #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "manuellt skapad" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "Tidslinjen" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Hantera ögonblicksbilder" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Skapade ögonblicksbild." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Lagring ögonblicksbildkonfiguration uppdaterad" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Åtgärdsfel: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Borttagna markerade ögonblicksbilder" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Ögonblicksbild används för närvarande. Vänligen försök igen senare." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Återställs till Snapshot #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Systemet måste startas om för att slutföra återställningen." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Återställning till ögonblicksbild" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6467,7 +6428,7 @@ msgstr "" "administrativa uppgifter, kopiera filer eller köra andra tjänster med sådana " "anslutningar." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Secure Shell-Server (SSH)" @@ -6505,14 +6466,6 @@ msgstr "Algoritm" msgid "Fingerprint" msgstr "Fingeravtryck" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "SSH-autentisering med lösenord inaktiverat." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "SSH-autentisering med lösenord aktiverat." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Enkel inloggning på" @@ -6525,7 +6478,7 @@ msgstr "Logga in" msgid "Logged out successfully." msgstr "Du har loggat ut framgångsrikt." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6536,106 +6489,106 @@ msgstr "" "{box_name}. Du kan visa lagringsmedia som för närvarande används, montera " "och demontera flyttbara media, expandera rotpartitionen etc." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Lagring" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} byte" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} Kib" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} Mib" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} Gib" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} Tib" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Åtgärden misslyckades." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Operationen avbröts." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Enheten lossnar redan." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "Åtgärden stöds inte på grund av saknade drivrutiner/verktygsstöd." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Åtgärden orsakade timeout." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "Åtgärden skulle väcka en disk som är i ett djupviloläge." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Försöker avmontera en enhet som är upptagen." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Operationen har redan avbrutits." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "Inte behörig att utföra den begärda åtgärden." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Enheten är redan monterad." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Enheten är inte monterad." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "Inte tillåtet att använda det begärda alternativet." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Enheten monteras av en annan användare." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Lågt utrymme på systempartitionen: {percent_used}% används, {free_space} " "fritt." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Lågt diskutrymme" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Diskfel förestående" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6644,39 +6597,39 @@ msgstr "" "Disk {id} rapporterar att den sannolikt kommer att misslyckas inom en snar " "framtid. Kopiera all data medan du fortfarande kan och byt ut enheten." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Ogiltigt katalognamn." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Katalogen finns inte." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Sökvägen är inte en katalog." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Katalogen är inte läsbar av användaren." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Katalogen är inte skrivbar av användaren." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Katalog" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Underkatalog (valfritt)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Share" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Annan katalog (specificera nedan)" @@ -6713,7 +6666,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Utöka root-partitionen" @@ -6736,30 +6689,30 @@ msgstr "" "åtgärden kommer %(expandable_root_size)s av ytterligare ledigt utrymme att " "vara tillgängligt i rotpartitionen." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Fel vid utökning av partitionen: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Partitionsutökning genomförd." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} kan kopplas ur på ett säkert sätt." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Enheten kan kopplas ur på ett säkert sätt." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Fel mata ut enhet: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6771,7 +6724,7 @@ msgstr "" "filer på en enhet kommer att replikeras automatiskt på alla andra enheter " "som också kör Syncthing." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6790,20 +6743,20 @@ msgstr "" "{box_name} är endast tillgängligt för användare som tillhör gruppen \"admin" "\" eller \"syncthing-access\"." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Administrera Syncthing-program" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Filsynkronisering" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6817,7 +6770,7 @@ msgstr "" "använder TOR Browser." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6826,40 +6779,40 @@ msgstr "" "En Tor SOCKS-port finns tillgängligt på din {box_name} för interna nätverk " "på TCP-port 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor Onion service" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor SOCKS-proxy" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor Bridge Relay" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor relä port tillgänglig" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 transport registrerad" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 transport registrerad" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Tillgång URL {url} på TCP {kind} via Tor" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Bekräfta Tor-användning vid {url} på TCP {kind}" @@ -6979,17 +6932,14 @@ msgstr "Onion tjänst" msgid "Ports" msgstr "Portar" -#: plinth/modules/tor/views.py:55 -#, fuzzy -#| msgid "Error updating configuration" +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" -msgstr "Fel vid uppdatering av konfiguration" +msgstr "Uppdatera konfigurationen" -#: plinth/modules/tor/views.py:72 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/modules/tor/views.py:70 +#, python-brace-format msgid "Error configuring app: {error}" -msgstr "Installationen misslyckades: {error}" +msgstr "Fel vid konfigurering av appen: {error}" #: plinth/modules/transmission/__init__.py:23 msgid "Transmission is a BitTorrent client with a web interface." @@ -7050,7 +7000,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7060,7 +7010,7 @@ msgstr "" "utformats för att läsa nyheter från vilken plats som helst, samtidigt som du " "känner dig så nära en riktig stationär applikation som möjligt." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7069,7 +7019,7 @@ msgstr "" "När aktiverat kan Tiny Tiny RSS nås av alla " "användare som tillhör gruppen feed-reader." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7077,11 +7027,11 @@ msgstr "" "När du använder en mobil eller stationär applikation för Tiny Tiny RSS, " "Använd URL/tt-rss-app/\" för att ansluta." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Läsare för nyhetsflödet" @@ -7089,13 +7039,13 @@ msgstr "Läsare för nyhetsflödet" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" "Sök efter och installera de senaste program-och säkerhetsuppdateringarna." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7108,22 +7058,22 @@ msgstr "" "systemet bedöms vara nödvändigt, det sker automatiskt vid 02:00 orsakar alla " "apps för att vara tillgängligt en kort stund." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Mjukvaruuppdatering" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox uppdaterad" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Det gick inte att starta distributionsuppdatering" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7134,11 +7084,11 @@ msgstr "" "Distributionsuppdateringen kommer att göras ett nytt behov efter 24 timmar, " "om det är aktiverat." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Distributionsuppdateringen har startats" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7299,63 +7249,59 @@ msgid "Show recent update logs" msgstr "Visa senaste uppdatering av loggar" #: plinth/modules/upgrades/templates/upgrades_configure.html:138 -#, fuzzy -#| msgid "Distribution upgrade enabled" msgid "Test Distribution Upgrade" -msgstr "Distributionsuppgradering aktiverad" +msgstr "Uppgradering av testdistribution" #: plinth/modules/upgrades/templates/upgrades_configure.html:140 msgid "" "This will attempt to upgrade the system from stable to testing. It " "is meant only for development use." msgstr "" +"Detta kommer att försöka uppgradera systemet från stabilt till testning. " +"Den är endast avsedd för utvecklingsanvändning." #: plinth/modules/upgrades/templates/upgrades_configure.html:150 -#, fuzzy -#| msgid "Distribution upgrade enabled" msgid "Test distribution upgrade now" -msgstr "Distributionsuppgradering aktiverad" +msgstr "Uppgradera testdistributionen nu" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "Fel vid konfigurering av obevakad uppgraderingar: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Automatiska uppgraderingar aktiverade" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Automatiska uppgraderingar inaktiverade" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Distributionsuppgradering aktiverad" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Distributionsuppgradering inaktiverad" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Uppgraderingsprocessen påbörjades." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Det gick inte att starta uppgraderingen." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Frekventa funktionsuppdateringar aktiverade." -#: plinth/modules/upgrades/views.py:223 -#, fuzzy -#| msgid "Distribution upgrade enabled" +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." -msgstr "Distributionsuppgradering aktiverad" +msgstr "Startar distributionsuppgraderingstest." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7366,7 +7312,7 @@ msgstr "" "ett användarkonto för att vara en del av en grupp för att auktorisera " "användaren att komma åt appen." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7377,15 +7323,15 @@ msgstr "" "över appar som är relevanta för dem på startsidan. Endast användare av " "gruppen admin kan dock ändra appar eller Systeminställningar." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Användare och grupper" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Tillgång till alla tjänster och systeminställningar" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Kontrollera LDAP-posten \"{search_item}\"" @@ -7405,11 +7351,11 @@ msgstr "" "Krävs. 150 tecken eller färre. Engelska bokstäver, siffror och endast @/./-/" "_ ." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Auktoriseringslösenord" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7417,11 +7363,11 @@ msgstr "" "Ange lösenordet för användaren \"{user}\" för att godkänna " "kontomodifieringar." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Ogiltigt lösenord." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7435,12 +7381,12 @@ msgstr "" "administratörsgruppen kommer att kunna logga in på alla tjänster. De kan " "också logga in på systemet via SSH och har administratörsprivilegier (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Det gick inte att skapa LDAP-användare: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Det gick inte att lägga till ny användare i gruppen {group} : {error}" @@ -7459,42 +7405,42 @@ msgstr "" "systemet utan att använda ett lösenord. Du kan ange flera nycklar, en på " "varje rad. Tomma rader och rader som börjar med # kommer att ignoreras." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Det gick inte att byta namn på LDAP-användare." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Det gick inte att ta bort användare från gruppen." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Det gick inte att lägga till användare i gruppen." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Det går inte att ange SSH-nycklar." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Det gick inte att ändra användarstatus." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Det gick inte att ändra användarlösenordet för LDAP." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" "Det gick inte att lägga till ny användare i administratörsgruppen: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Det gick inte att begränsa konsolåtkomst: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Användarkonto skapat, du är nu inloggad" @@ -7511,12 +7457,12 @@ msgstr "Spara lösenord" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Skapa användare" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Ta bort användare" @@ -7557,13 +7503,19 @@ msgid "The following administrator accounts exist in the system." msgstr "Följande administratörskonton finns i systemet." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Ta bort dessa konton från kommandoraden och uppdatera sidan för att skapa " "ett konto som är användbart med %(box_name)s. På kommandoraden kör kommandot " @@ -7572,7 +7524,7 @@ msgstr "" "detta steg." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Användare" @@ -7605,34 +7557,34 @@ msgstr "" msgid "Save Changes" msgstr "Spara ändringar" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Användaren %(username)s skapades." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Användaren %(username)s har uppdaterats." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Redigera användar" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Användare {user} borttagen." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Det gick inte att ta bort LDAP-användare." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Ändra lösenord" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Lösenordet har ändrats." @@ -7970,7 +7922,7 @@ msgstr "Ta bort anslutning till server" msgid "Server deleted." msgstr "Servern har tagits bort." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7984,7 +7936,7 @@ msgstr "" "med hjälp av teman. Administrationsgränssnittet och producerade webbsidor är " "lämpliga för mobila enheter." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7998,7 +7950,7 @@ msgstr "" "administratörsgränssnittet för bättre webbadresser till dina sidor och " "inlägg." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8009,7 +7961,7 @@ msgstr "" "sidan som ett bokmärke för att nå administrationsgränssnittet i " "framtiden." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8019,12 +7971,12 @@ msgstr "" "databasuppgradering från administratörsgränssnittet. Ytterligare plugins " "eller teman kan installeras och uppgraderas på egen risk." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Webbplats och blogg" @@ -8041,7 +7993,7 @@ msgstr "" "WordPress-webbplatsen eller bloggen. Aktivera endast efter den första " "installationen av WordPress." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8062,7 +8014,7 @@ msgstr "" "på en plats med hjälp av sök-, kart- och kalendervyer. Enskilda foton kan " "delas med andra genom att skicka en direktlänk." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8073,11 +8025,11 @@ msgstr "" "i Zoph. För ytterligare användare måste konton skapas både i {box_name} och " "i Zoph med samma användarnamn." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Foto Organizer" @@ -8116,134 +8068,108 @@ msgid "Generic" msgstr "Generiska" #: plinth/operation.py:116 -#, fuzzy, python-brace-format -#| msgid "Error setting hostname: {exception}" +#, python-brace-format msgid "Error: {name}: {exception_message}" -msgstr "Fel inställning av värdnamn: {exception}" +msgstr "Fel: {name}: {exception_message}" #: plinth/operation.py:119 #, python-brace-format msgid "Waiting to start: {name}" -msgstr "" +msgstr "Väntar på att starta: {name}" #: plinth/operation.py:125 -#, fuzzy, python-brace-format -#| msgid "Service disabled: {name}" +#, python-brace-format msgid "Finished: {name}" -msgstr "Tjänsten är inaktiverad: {name}" +msgstr "Avslutad: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "Paket {expression} är inte tillgänglig för installation" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Paketet {package_name} är den senaste versionen ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Fel under säkerhetskopiering" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "Installera" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "ladda ner" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "Mediabyte" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "konfigurationsfil: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" -msgstr "" +msgstr "Timeout väntar på pakethanteraren" -#: plinth/setup.py:40 -#, fuzzy -#| msgid "Install Apps" +#: plinth/setup.py:41 msgid "Installing app" -msgstr "Installera appar" +msgstr "Installera app" -#: plinth/setup.py:42 -#, fuzzy -#| msgid "Updating..." +#: plinth/setup.py:43 msgid "Updating app" -msgstr "Uppdatera..." +msgstr "Uppdatera app" -#: plinth/setup.py:68 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {string} {details}" +#: plinth/setup.py:69 +#, python-brace-format msgid "Error installing app: {string} {details}" -msgstr "Installation misslyckades: {string} {details}" +msgstr "Fel vid installation av app: {string} {details}" -#: plinth/setup.py:72 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {string} {details}" +#: plinth/setup.py:73 +#, python-brace-format msgid "Error updating app: {string} {details}" -msgstr "Installation misslyckades: {string} {details}" +msgstr "Fel vid uppdatering av app: {string} {details}" -#: plinth/setup.py:78 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/setup.py:79 +#, python-brace-format msgid "Error installing app: {error}" -msgstr "Installationen misslyckades: {error}" +msgstr "Fel vid installation av app: {error}" -#: plinth/setup.py:81 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/setup.py:82 +#, python-brace-format msgid "Error updating app: {error}" -msgstr "Installationen misslyckades: {error}" +msgstr "Fel vid uppdatering av app: {error}" -#: plinth/setup.py:85 -#, fuzzy -#| msgid "Application installed." +#: plinth/setup.py:86 msgid "App installed." -msgstr "Applikation installerad." +msgstr "App installerad." -#: plinth/setup.py:87 -#, fuzzy -#| msgid "Last update" +#: plinth/setup.py:88 msgid "App updated" -msgstr "Senaste uppdatering" +msgstr "App uppdaterad" -#: plinth/setup.py:104 -#, fuzzy -#| msgid "Install Apps" +#: plinth/setup.py:105 msgid "Uninstalling app" -msgstr "Installera appar" +msgstr "Avinstallera app" -#: plinth/setup.py:122 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {string} {details}" +#: plinth/setup.py:123 +#, python-brace-format msgid "Error uninstalling app: {string} {details}" -msgstr "Installation misslyckades: {string} {details}" +msgstr "Fel vid avinstallation av app: {string} {details}" -#: plinth/setup.py:128 -#, fuzzy, python-brace-format -#| msgid "Error installing application: {error}" +#: plinth/setup.py:129 +#, python-brace-format msgid "Error uninstalling app: {error}" -msgstr "Installationen misslyckades: {error}" +msgstr "Fel vid avinstallation av appen: {error}" -#: plinth/setup.py:131 -#, fuzzy -#| msgid "Application installed." +#: plinth/setup.py:132 msgid "App uninstalled." -msgstr "Applikation installerad." +msgstr "Appen avinstallerad." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" -msgstr "" +msgstr "Uppdatera appaket" #: plinth/templates/403.html:10 msgid "403 Forbidden" @@ -8300,53 +8226,54 @@ msgstr "Installation" msgid "Service %(service_name)s is not running." msgstr "Tjänsten %(service_name)s körs inte." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Kärnfunktioner och webbgränssnitt för %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Hem" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Hem" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Appar" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Appar" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " System" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "System" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Ändra lösenord" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Stänga ner" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Logga ut" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Välj språk" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Logga in" @@ -8604,26 +8531,25 @@ msgstr "Uppdatera" #: plinth/templates/toolbar.html:39 plinth/templates/toolbar.html:40 #: plinth/templates/uninstall.html:36 -#, fuzzy -#| msgid "Install" msgid "Uninstall" -msgstr "Installera" +msgstr "avinstallera" #: plinth/templates/uninstall.html:11 -#, fuzzy, python-format -#| msgid "Edit User %(username)s" +#, python-format msgid "Uninstall App %(app_name)s?" -msgstr "Redigera användare %(username)s" +msgstr "Avinstallera app %(app_name)s?" #: plinth/templates/uninstall.html:17 msgid "Uninstalling an app is an exprimental feature." -msgstr "" +msgstr "Att avinstallera en app är en experimentell funktion." #: plinth/templates/uninstall.html:23 msgid "" "All app data and configuration will be permanently lost. App may be " "installed freshly again." msgstr "" +"All appdata och konfiguration kommer att gå förlorad permanent. Appen kan " +"installeras på nytt igen." #: plinth/views.py:221 msgid "Setting unchanged" @@ -8632,12 +8558,81 @@ msgstr "Instänllningar oförändrade" #: plinth/views.py:401 #, python-brace-format msgid "before uninstall of {app_id}" -msgstr "" +msgstr "innan du avinstallerar {app_id}" #: plinth/web_framework.py:114 msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Aktivera DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Aktivera Domain Name System Security Extensions" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Brandväggsdemonen körs inte. Vänligen starta den. Brandväggen är " +#~ "aktiverad som standard på %(box_name)s. På ett Debian-baserade system " +#~ "(till exempel %(box_name)s) Du kan starta den med kommandot \"service " +#~ "firewalld start\", alternativt, vid ett system med systemd \"systemctl " +#~ "start firewalld\"." + +#~ msgid "Migrate to ECC" +#~ msgstr "Migrera till ECC" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "Din OpenVPN-installation använder för närvarande RSA. Om du byter till " +#~ "den moderna Elliptic Curve Cryptography förbättrar hastigheten för att " +#~ "upprätta en anslutning och säkerhet. Den här åtgärden är oåterkallelig. " +#~ "Det bör bara ta några minuter på de flesta enda ombord datorer." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "Alla nya installationer av OpenVPN på %(box_name)s kommer att använda ECC " +#~ "som standard. Vi rekommenderar migrering så snart som möjligt." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ " Varning: Befintliga klientprofiler kommer att ogiltigförklaras av " +#~ "den här åtgärden. Alla OpenVPN-användare på %(box_name)s måste hämta sina " +#~ "nya profiler. OpenVPN-klienter som är kompatibla med ECC bör användas för " +#~ "att ansluta till den här servern." + +#~ msgid "Migrate" +#~ msgstr "Flytta" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "SSH-autentisering med lösenord inaktiverat." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "SSH-autentisering med lösenord aktiverat." + +#~ msgid "Error running apt-get" +#~ msgstr "Fel vid körning av apt-get" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Kärnfunktioner och webbgränssnitt för %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Nätverksanslutningar" diff --git a/plinth/locale/ta/LC_MESSAGES/django.po b/plinth/locale/ta/LC_MESSAGES/django.po index 580ba897d..e96490446 100644 --- a/plinth/locale/ta/LC_MESSAGES/django.po +++ b/plinth/locale/ta/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -110,17 +110,17 @@ msgstr "" msgid "{box_name} Web Interface (Plinth)" msgstr "" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -131,48 +131,48 @@ msgid "" "network." msgstr "" -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "" -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." msgstr "" -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " "succeed. The latest error is: {error_message}" msgstr "" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "" @@ -304,7 +304,7 @@ msgstr "" msgid "Key in Repository" msgstr "" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "" @@ -368,37 +368,37 @@ msgstr "" msgid "Select verified SSH public key" msgstr "" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." msgstr "" -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "" -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "" @@ -453,7 +453,7 @@ msgid "Create Location" msgstr "" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "" @@ -676,7 +676,7 @@ msgstr "" msgid "Mounting failed" msgstr "" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -684,7 +684,7 @@ msgid "" "can be set to expire after a time period." msgstr "" -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -692,7 +692,7 @@ msgid "" "permissions." msgstr "" -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -700,39 +700,39 @@ msgid "" "the list." msgstr "" -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "" @@ -746,7 +746,7 @@ msgstr "" #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "" @@ -779,35 +779,35 @@ msgstr "" #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -819,41 +819,41 @@ msgstr "" msgid "Delete" msgstr "" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "" -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "" -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "" -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "" -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." msgstr "" -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -861,31 +861,23 @@ msgid "" "connection from {box_name}." msgstr "" -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "" @@ -917,19 +909,20 @@ msgstr "" msgid "Refresh IP address and domains" msgstr "" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -937,7 +930,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -946,35 +939,35 @@ msgid "" "highlighted text. Content distribution using OPDS is currently not supported." msgstr "" -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." msgstr "" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "" @@ -1020,20 +1013,20 @@ msgstr "" msgid "Delete library %(library)s" msgstr "" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "" @@ -1071,24 +1064,24 @@ msgstr "" msgid "Server Administration" msgstr "" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1184,47 +1177,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1232,7 +1225,7 @@ msgid "" "who are otherwise unable connect to each other." msgstr "" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ddns." @@ -1462,11 +1455,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1578,7 +1571,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1633,13 +1626,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1761,14 +1754,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1776,7 +1769,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1786,13 +1779,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -1917,7 +1910,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -1925,7 +1918,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -1945,61 +1938,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2045,7 +2029,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2056,73 +2040,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2166,19 +2150,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2471,7 +2455,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2479,31 +2463,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2540,14 +2524,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2556,15 +2540,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2618,41 +2602,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2660,11 +2644,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2710,7 +2694,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2728,7 +2712,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2738,7 +2722,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2746,15 +2730,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2817,41 +2801,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2861,14 +2845,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -2949,7 +2933,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -2957,7 +2941,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -2966,18 +2950,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3046,35 +3030,35 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3083,11 +3067,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3132,7 +3116,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3291,19 +3275,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3649,7 +3633,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3754,7 +3738,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3770,7 +3754,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3783,7 +3767,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4319,7 +4303,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4330,20 +4314,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4353,61 +4337,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4416,33 +4368,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4451,87 +4403,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4565,29 +4517,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4629,8 +4581,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4672,6 +4624,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4703,7 +4686,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4714,7 +4697,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4734,7 +4717,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4744,19 +4727,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4815,7 +4798,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4882,7 +4865,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -4895,13 +4878,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -4910,31 +4893,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5012,15 +4995,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5046,51 +5029,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5243,14 +5226,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5259,97 +5242,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5386,26 +5369,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5413,14 +5396,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5514,7 +5497,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5562,57 +5545,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5620,7 +5603,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5653,14 +5636,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5673,7 +5648,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5681,143 +5656,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5851,7 +5826,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5869,30 +5844,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -5900,7 +5875,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -5912,20 +5887,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -5934,47 +5909,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6072,11 +6047,11 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "" @@ -6128,31 +6103,31 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " "user belonging to the feed-reader group." msgstr "" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6160,12 +6135,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6173,33 +6148,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6347,51 +6322,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6399,15 +6374,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6425,21 +6400,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6448,12 +6423,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6469,41 +6444,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6520,12 +6495,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6563,17 +6538,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6604,34 +6579,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -6940,7 +6915,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -6949,7 +6924,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -6958,26 +6933,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -6991,7 +6966,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7004,7 +6979,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7012,11 +6987,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7065,96 +7040,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7205,53 +7176,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" diff --git a/plinth/locale/te/LC_MESSAGES/django.po b/plinth/locale/te/LC_MESSAGES/django.po index 7f50f1f9e..0a29552be 100644 --- a/plinth/locale/te/LC_MESSAGES/django.po +++ b/plinth/locale/te/LC_MESSAGES/django.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: FreedomBox UI\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-03-02 12:27+0000\n" "Last-Translator: James Valleroy \n" "Language-Team: Telugu calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1019,29 +1012,29 @@ msgstr "" "calibre సమూహానికి చెందిన వినియోగదారులు మాత్రమే యాప్‌ని యాక్సెస్ చేయగలరు. యాక్సెస్ ఉన్న " "వినియోగదారులందరూ అన్ని గ్రంధాలయంను ఉపయోగించవచ్చు" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "క్యాలిబర్ ఇ-బుక్ లైబ్రరీ ఉపయోగించండి" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "క్యాలిబర్" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "ఇ-బుక్ లైబ్రరీ" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "కొత్త గ్రంధాలయం పేరు" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "ఈ పేరుతో గ్రంధాలయం ఇప్పటికే ఉంది." @@ -1087,20 +1080,20 @@ msgstr "%(library)s లైబ్రరీకి వెళ్లుము" msgid "Delete library %(library)s" msgstr "గ్రంధాలయంను తొలగించు %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "గ్రంధాలయంను సృష్టించారు." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "గ్రంధాలయంని సృష్టిస్తున్నప్పుడు లోపం సంభవించింది." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} తొలగించబడింది." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "{name} ను తొలగించలేము: {error}" @@ -1146,7 +1139,7 @@ msgstr "కాక్పిట్" msgid "Server Administration" msgstr "సేవిక పరిపాలన" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1154,18 +1147,18 @@ msgstr "" "ఇక్కడ మీరు ఆతిథ్య నామం అధికారక్షేత్రం మహాతలంసేవిక మొదలైన కొన్ని సాధారణ రూపకరణ ఎంపికలను అమరిక " "చేయవచ్చు." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "సాధారణ ఆకృతీకరణ" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "ఆకృతీకరణ" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1276,47 +1269,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "ఆతిథ్యనామం అమర్చుటలో లోపం: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "ఆతిథ్యనామం అమర్చు" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "అధికారక్షేత్రం పేరు అమర్పులోపం: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "అధికారక్షేత్రం పేరు అమర్పు" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "వెబ్‌సర్వర్ హోమ్ పేజీని సెట్ చేయడంలో లోపం: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "వెబ్ సర్వర్ హోమ్ పేజీ సెట్ చేయబడింది" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "అధికారక్షేత్రం పేరు అమర్పులోపం: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "అధునాతన అనువర్తనాలు మరియు విశేషాంశాలు చూపబడుతున్నాయి" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "అధునాతన అనువర్తనాలు మరియు విశేషాంశాలు దాచబడుతున్నాయి" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1327,7 +1320,7 @@ msgstr "" "సమావేశాలను సులభతరం చేయడానికి ఒక సర్వర్. WebRTC, SIP మరియు ఇతర కమ్యూనికేషన్ సర్వర్‌లు ఒకదానికొకటి " "కనెక్ట్ చేయలేని పార్టీల మధ్య కాల్‌ని ఏర్పాటు చేయడానికి దీన్ని ఉపయోగించవచ్చు." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse or ejabberd ఇక్కడ అందించిన వివరాలతో రూపకరణచేయాలి." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "కోటుర్న్" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "విఓఐపీ సహాయకుడు" @@ -1397,11 +1390,11 @@ msgstr "సమయమండలం అమర్పులోపం: {exception}" msgid "Time zone set" msgstr "సమయమండలం ఏర్పాటు చేయబడినది" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "డీలడ్జ్ అనేది జాల UI కలిగివున్న ఒక బిట్ టోరెంట్ కక్షిదారు." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1410,16 +1403,16 @@ msgstr "" "a> అనే మార్గంలో అందుబాటులోనుంటుంది. ప్రధమ పాస్‌వర్డ్ గా 'డెల్యూజ్' ఉంటుంది, కానీ మీరు లాగ్ ఇన్ " "అయినవెంటనే మీ పాస్‌వర్డ్ ను మార్చుకోవాలి." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "బిట్ టోరెంట్ అనువర్తనాలను ఉపయోగించి ఫైళ్లను డౌన్లోడ్ చేయండి" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "డెలూజ్" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "బిట్ టొరెంట్ వెబ్ క్లయింట్" @@ -1545,7 +1538,7 @@ msgstr "ఫలితం" msgid "Diagnostic Test" msgstr "లక్షణాల పరీక్ష" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1556,7 +1549,7 @@ msgstr "" "అప్పుడు ఇతరులు అంతర్జాలంలో మిమల్ని కనుగొనడానికి కష్టం ఆవతుంది. అప్పుడు వారు ఈ {box_name} " "అందించే సేవలను కనుగోనలేరు." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1572,7 +1565,7 @@ msgstr "" "అనుమతిస్తుంది. తరువాత, సర్వర్ కొత్త IP మీ DNS పేరు కేటాయిస్తుంది, మరియు ఇంటర్నెట్ నుండి ఎవరైనా మీ " "DNS పేరు అడుగుతాడు ఉంటే, వారు మీ ప్రస్తుత ఐ.పీ. చిరునామాతో సమాధానం పొందుతారు." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1585,11 +1578,11 @@ msgstr "" "\" target=\"_blank\"> 3 freedns.afraid.org 4 ఉచిత నవీకరణ URL ఆధారిత సేవలు " "కనుగొనవచ్చు." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "గతిక DNS కక్షిదారు" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "డైనమిక్ డొమైన్ పేరు" @@ -1713,7 +1706,7 @@ msgstr "ఇది అవసరమేయిన్న క్షేత్రం." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1768,7 +1761,7 @@ msgstr "సర్వర్ కనెక్షన్ నిరాకరించ msgid "Already up-to-date" msgstr "ఇప్పటికే తాజాగా ఉంది" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1776,7 +1769,7 @@ msgstr "" "XMPP ఓపెన్ మరియు ప్రామాణికమైన కమ్యూనికేషన్ ప్రోటోకాల్. ఇక్కడ మీరు మీ XMPP సర్వర్ ని రూపకరణ మరియు " "అమలు చేయగలరు ejabberd అని ఆకృతీకరించవచ్చు." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client. ప్రారంభించబడినప్పుడు, ejabberdని ఏ " "వినియోగదారు అయినా {box_name} లాగిన్‌తో యాక్సెస్ చేయవచ్చు." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, fuzzy, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the kaanfigar పేజీలో సెటప్ చేయవచ్చు." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1935,7 +1928,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1945,7 +1938,7 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -1953,7 +1946,7 @@ msgstr "" "Roundcube యాప్ వినియోగదారులు ఇమెయిల్‌ను యాక్సెస్ " "చేయడానికి వెబ్ ఇంటర్‌ఫేస్‌ను అందిస్తుంది." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2082,7 +2075,7 @@ msgstr "పోర్టు" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2092,7 +2085,7 @@ msgstr "" "ఫైర్వాల్ అనేది మీ {box_name}కు జరిగే రవాణా రాకపోకలను నియంత్రించే ఒక భద్రతా వ్యవస్థ. దీనిని అనుమతించి " "సరిగా ఆకృతీకరిస్తే అంతర్జాలం నుంచి భద్రతా ముప్పు తగ్గుతుంది." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "ఫైర్వాల్" @@ -2112,52 +2105,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Port {name} ({details})బాహ్య నెట్‌వర్క్‌లకు అందుబాటులో లేదు" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"ఫైర్‌వాల్ డెమోన్ రన్ కావడం లేదు. దయచేసి దీన్ని అమలు చేయండి. %(box_name)sలో ఫైర్‌వాల్ డిఫాల్ట్‌గా " -"ప్రారంభించబడింది. ఏదైనా డెబియన్ ఆధారిత సిస్టమ్‌లో (%(box_name)s వంటివి) మీరు 'సర్వీస్ ఫైర్‌వాల్డ్ స్టార్ట్' " -"కమాండ్‌ని ఉపయోగించి లేదా systemd 'systemctl start firewalld' ఉన్న సిస్టమ్ విషయంలో దీన్ని అమలు " -"చేయవచ్చు." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "సేవ/పోర్ట్" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "క్రియాశీలం" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "నిలిపివేయబడింది" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "అనుమతించబడిన" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "అనుమతించబడిన (అంతర్గతంగా మాత్రమే)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "అనుమతించబడిన(బాహ్యం మాత్రమే)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "నిరోధించబడినవి" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2166,13 +2146,13 @@ msgstr "" "ఫైర్వాల్ పనితీరు స్వయాంచలికమైనది. మీరు ఒక సేవను అనుమతిస్తే అది ఫైర్వాల్లోకి కూడా అనుమతిచబడుతుంది. అలాగే " "మీరు ఒక సేవను ఆనుమతించకపోతే ఫైర్వాల్లో కూడా అది అనుమతింపబడదు." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "ఉన్నత స్థితి" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2224,7 +2204,7 @@ msgstr "అమరికను ప్రారంభించు" msgid "Setup Complete" msgstr "అమరక పూర్తయ్యింది" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2241,7 +2221,7 @@ msgstr "" "క్లయింట్‌లతో కోడ్ మార్పులను అప్‌లోడ్ చేయవచ్చు. మరియు మీరు మీ కోడ్‌ని ప్రపంచవ్యాప్తంగా ఉన్న వ్యక్తులతో " "పంచుకోవచ్చు." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2249,69 +2229,69 @@ msgstr "" "Gitని ఎలా ఉపయోగించాలో మరింత తెలుసుకోవడానికి Git ట్యుటోరియల్ని సందర్శించండి." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Git రిపోజిటరీలకు చదవడానికి-వ్రాయడానికి యాక్సెస్" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "గిట్వెబ్" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "సాధారణ Git హోస్టింగ్" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "చెల్లని రిపోజిటరీ URL." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "చెల్లని రిపోజిటరీ పేరు." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "ఇప్పటికే ఉన్న రిపోజిటరీని దిగుమతి చేయడానికి కొత్త రిపోజిటరీ పేరు లేదా URL." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "రిపోజిటరీ వివరణ" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "ఐచ్ఛికం, గిట్‌వెబ్‌లో ప్రదర్శించడానికి." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "రిపోజిటరీ యొక్క యజమాని పేరు" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "స్వంత రిపోజిటరీ" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "ఈ రిపోజిటరీని యాక్సెస్ చేయడానికి అధికారం ఉన్న వినియోగదారులను మాత్రమే అనుమతించండి." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "ఈ పేరుతో ఒక రిపోజిటరీ ఇప్పటికే ఉంది." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "రిపోజిటరీ పేరు" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" "భాగస్వామ్యాన్ని ప్రత్యేకంగా గుర్తించే లోయర్‌కేసన్ ఆల్ఫా-న్యూమరిక్ స్ట్రింగ్. ఉదాహరణ: <em>మీడియా</" "em>రిపోజిటరీ." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "డిఫాల్ట్ చర్మం" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb దీన్ని డిఫాల్ట్ బ్రాంచ్‌గా ప్రదర్శిస్తుంది." @@ -2355,19 +2335,19 @@ msgstr "Git రిపోజిటరీ %(name)sని తొలగి msgid "Delete this repository permanently?" msgstr "ఈ రిపోజిటరీని శాశ్వతంగా తొలగించాలా?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "రిపోజిటరీ సృష్టించబడింది." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "రిపోజిటరీని సృష్టిస్తున్నప్పుడు లోపం సంభవించింది." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "రిపోజిటరీ సవరించబడింది." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "రిపోజిటరీని సవరించండి" @@ -2716,7 +2696,7 @@ msgstr "{box_name} గురించి" msgid "{box_name} Manual" msgstr "{box_name} కరదీపిక" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2727,7 +2707,7 @@ msgstr "" "అనామక నెట్‌వర్క్ లేయర్. I2P ప్రపంచవ్యాప్తంగా పంపిణీ చేయబడిన వాలంటీర్-రన్ నెట్‌వర్క్ ద్వారా ఎన్‌క్రిప్టెడ్ ట్రాఫిక్‌ను " "పంపడం ద్వారా అనామకతను అందిస్తుంది." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2735,25 +2715,25 @@ msgstr "" "వారి పథకం హోమ్‌పేజీలో I2P గురించి " "మరింత సమాచారాన్ని కనుగొనండి." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "అందించిన వెబ్ ఇంటర్‌ఫేస్‌కు మొదటి సందర్శన కాన్ఫిగరేషన్ ప్రక్రియను ప్రారంభిస్తుంది." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "I2P కార్యక్షేతాన్ని నిర్వహించండి" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "ఇ౨ప్" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "అజ్ఞాత జాలిక" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P ప్రాతినిధ్య" @@ -2797,7 +2777,7 @@ msgstr "" "జోడించడం ద్వారా దస్త్రంలను సమాచార దిగుమతి చేయండి లేదా దస్త్రంలను భాగస్వామ్యం చేయడానికి కొత్త టొరెంట్‌ని " "సృష్టించండి." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2806,7 +2786,7 @@ msgstr "" "ikiwiki అనేది ఒక సాధారణ వికీ మరియు బ్లాగ్ అప్లికేషన్. ఇది మార్క్‌డౌన్‌తో సహా పలు తేలికపాటి మార్కప్ భాషలకు " "మరియు వ్యాఖ్యలు మరియు RSS ఫీడ్‌ల వంటి సాధారణ బ్లాగింగ్ కార్యాచరణకు మద్దతు ఇస్తుంది." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2819,15 +2799,15 @@ msgstr "" "సమూహం ఇప్పటికే ఉన్న వాటిని సవరించవచ్చు. వినియోగదారు " "కాన్ఫిగరేషన్లో మీరు ఈ అనుమతులను మార్చవచ్చు లేదా కొత్త వినియోగదారులను జోడించవచ్చు." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ఇకివికీ" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "వికీ మరియు బ్లాగ్" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "వికీ అనువర్తనాలను చూడండి మరియు మార్చండి" @@ -2883,41 +2863,41 @@ msgstr "" "ఈ చర్య పునర్విమర్శ చరిత్రతో సహా అన్ని పోస్ట్లు, పుటలు మరియు వ్యాఖ్యలు తొలగిస్తుంది. ఈ వికీ లేదా బ్లాగ్ " "శాశ్వతంగా తొలగించాలా?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "{name} వికీ సృష్టించబడింది." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "వికీని సృష్టించలేము: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "{name} బ్లాగు సృష్టించబడింది." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "బ్లాగు సృష్టించలేము: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} తొలగించబడింది." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "{title} ను తొలగించలేము: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "Gobby కోసం ఇన్ఫినోటెడ్ అనేది ఒక సర్వర్,ఒక సహకార టెక్స్ట్ ఎడిటర్." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2928,11 +2908,11 @@ msgstr "" "మరియు నిక్షిప్తం చెయుము. మొడటిగ గాబ్బి మరియు సెలెక్ట్ \"సర్వర్కు కనెక్ట్ చేయండి\" మరియు మీ ఎంటర్ చెయ్యండి " "{box_name}'s డొమైన్ పేరు." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "ఇన్ఫినోటెడ్" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "గాబ్బీ సేవకం" @@ -2980,7 +2960,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "జావాస్క్రిప్ట్ లైసెన్స్ సమాచరం" @@ -2999,7 +2979,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "చాట్ క్లయింట్" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3013,7 +2993,7 @@ msgstr "" "స్వయం చాలక డిజిటల్ సర్టిఫికెట్‌లను పొందవచ్చు మరియు అమర్చిపెట్టు చేయగలదు. ఇది సర్టిఫికేట్ అథారిటీ (CA) " "లెట్స్ ఎన్‌క్రిప్ట్‌కు అధికారక్షేత్రం యజమాని అని నిరూపించుకోవడం ద్వారా అలా చేస్తుంది." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3025,15 +3005,15 @@ msgstr "" "\"https://letsencrypt.org/repository/\">సభ్యుల ఒప్పందాన్ని ఎన్‌క్రిప్ట్ చేద్దాంని చదివి, " "అంగీకరించండి." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "లెట్స్ ఎన్క్రిప్ట్" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "యోగ్యతాపత్రాలు" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "పరీక్షించడం సాధ్యం కాదు: డొమైన్‌లు ఏవీ కాన్ఫిగర్ చేయబడలేదు." @@ -3098,7 +3078,7 @@ msgstr "" "తోబుట్టువుల అధికారక్షేత్రం కన్ఫిగర్ చేయబడ్డాయి. వారికి సర్టిఫికేట్లు పొందగలగటం అధికారక్షేత్రం " "ఆకృతీకరించుము. %(config_url)s" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3107,34 +3087,34 @@ msgstr "" "డొమైన్ {domain} కోసం సర్టిఫికేట్ విజయవంతంగా ఉపసంహరించబడింది. ఇది అమలులోకి రావడానికి కొన్ని క్షణాలు " "పట్టవచ్చు." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "{domain} డోమైన్ కొరకు సర్టిఫికేట్ ఉప్సంహరుంచుకొనడంలో విఫలం: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "{domain} డోమైన్ కొరకు సర్టిఫికేట్ సంపాదింపబడింది" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "{domain} డోమైన్ కొరకు సర్టిఫికేట్ సంపాదించుటలో విఫలం: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "{domain} డోమైన్ కొరకు సర్టిఫికేట్ తొలగించబడింది" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "{domain} డోమైన్ కొరకు ధృవీకరణపత్రం నిర్మూలించడంలో విఫలం: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3149,7 +3129,7 @@ msgstr "" "అందిస్తుంది మరియు పని చేయడానికి ఫోన్ నంబర్‌లు అవసరం లేదు. ఇచ్చిన మ్యాట్రిక్స్ సర్వర్‌లోని వినియోగదారులు " "ఫెడరేషన్ ద్వారా అన్ని ఇతర మ్యాట్రిక్స్ సర్వర్‌లలోని వినియోగదారులతో సంభాషించవచ్చు." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3158,7 +3138,7 @@ msgstr "" "Matrix Synapseకి ఆడియో/వీడియో కాల్‌ల కోసం STUN/TURN సర్వర్ అవసరం.Coturn యాప్‌ను ఇన్‌స్టాల్ చేయండి లేదా బాహ్య సర్వర్‌ను కాన్ఫిగర్ చేయండి." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "మ్యాట్రిక్స్ సినాప్స్" @@ -3258,7 +3238,7 @@ msgstr "" "కూడిన ఫెడరేషన్‌కు చెల్లుబాటు అయ్యే TLS ప్రమాణపత్రం అవసరం. దయచేసి ఒకదాన్ని పొందడానికి లెట్స్ ఎన్‌క్రిప్ట్కి వెళ్లండి." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3269,7 +3249,7 @@ msgstr "" "వెబ్సైటు నిర్మించే ఒక ఉపకరం. మీరు మీడియావికీని ఉపయోగించి ఒక వికీ లాంటి వెబ్సైటును ఏర్పాటు చేస్కుని మీ " "స్నేహితులతో సంయుక్తంగా నోట్స్ తీసుకొనవచ్చు." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3282,19 +3262,19 @@ msgstr "" "Special:" "CreateAccount పేజీకి వెళ్లడం ద్వారా MediaWiki నుండే మరిన్ని వినియోగదారు ఖాతాలను సృష్టించవచ్చు." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" "ఈ వికీకి లింక్తో ఎవరైనా దానిని చదవగలరు. లాగిన్ చేయబడిన వినియోగదారులు మాత్రమే కంటెంట్కు మార్పులు చేయవచ్చు." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "మీడియావికీ" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "వికీ" @@ -3383,39 +3363,39 @@ msgstr "అనుమతిపదం నవీకరించబడింది" msgid "Password update failed. Please choose a stronger password" msgstr "సమాచారాన్ని గుప్తీకరించాడానికి ఉపయోగించబడిన పాస్వర్డ్. తప్పకుండ సర్వర్ పాస్వర్డ్ తో సరిపోలాలి." -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "పబ్లిక్ రిజిస్ట్రేషన్లు ప్రారంభించబడ్డాయి" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "పబ్లిక్ రిజిస్ట్రేషన్లు నిలిపివేయబడ్డాయి" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "ప్రైవేట్ మోడ్ ప్రారంభించబడింది" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "ప్రైవేట్ మోడ్ నిలిపివేయబడింది" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "డిఫాల్ట్ చర్మం మార్చబడింది" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "అధికారక్షేత్రం పేరు అమర్పు" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "అధికారక్షేత్రం పేరు అమర్పు" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3427,11 +3407,11 @@ msgstr "" "{box_name}లో Minetest సర్వర్‌ని అమలు చేయడానికి అనుమతిస్తుంది. సర్వర్‌కి కనెక్ట్ చేయడానికి, Minetest క్లయింట్ అవసరం." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "మైన్ టెస్ట్" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "బ్లాక్ శాండ్‌బాక్స్‌" @@ -3479,7 +3459,7 @@ msgstr "నిరుపయోగం అయినప్పుడు, ఆటగా msgid "Address" msgstr "చిరునామా" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3665,7 +3645,7 @@ msgstr "సెక్యూర్ షెల్" msgid "Services" msgstr "సేవలు" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3673,13 +3653,13 @@ msgstr "" "కాన్ఫిగర్ చేయగల నెట్‌వర్క్ పరికరాలు. ఈథర్నెట్ మరియు Wi-Fi లేదా PPPoE ద్వారా ఇంటర్నెట్‌తో కనెక్ట్ అవ్వండి. " "నెట్‌వర్క్‌లోని ఇతర పరికరాలతో ఆ కనెక్షన్‌ని భాగస్వామ్యం చేయండి." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "ఇతర పద్ధతుల ద్వారా నిర్వహించబడే పరికరాలు ఇక్కడ ఆకృతీకరణకు అందుబాటులో ఉండకపోవచ్చు." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "అల్లికలు" @@ -4086,7 +4066,7 @@ msgstr "అనుసంధానాన్ని సవరించు" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "సవరించు" @@ -4191,7 +4171,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "పద్దతి" @@ -4207,7 +4187,7 @@ msgstr "సేవిక" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "అప్రమేయం" @@ -4220,7 +4200,7 @@ msgid "This connection is not active." msgstr "ఈ అనుసంధానం చురుకుగాలేదు." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "భద్రత" @@ -4792,7 +4772,7 @@ msgstr "{name} అనుసంధానం తొలగించబడింద msgid "Failed to delete connection: Connection not found." msgstr "అనుసంధానం తొలగించడం విఫలమైంది: అనుసంధానం దొరకలేదు." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4808,20 +4788,20 @@ msgstr "" "మిగిలిన ఇంటర్నెట్ను యాక్సెస్ చేయవచ్చు మీ {box_name} 1 అనుసంధానించవచ్చు అదనపు భద్రత మరియు " "అనామకత్వం కోసం." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "అనుసంధాన రకం విపిన్ సేవలకు" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "తెరచిన విపిన్" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "వర్చువల్ ప్రైవేట్ నెట్వర్క్" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4832,56 +4812,16 @@ msgstr "" msgid "Tunnelblick" msgstr "టన్నెల్‌బ్లిక్" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "ECCకి మైగ్రేట్ చేయండి" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"మీ OpenVPN ఇన్‌స్టాలేషన్ ప్రస్తుతం RSAని ఉపయోగిస్తోంది. ఆధునిక ఎలిప్టిక్ కర్వ్ క్రిప్టోగ్రఫీకి మారడం కనెక్షన్ " -"మరియు భద్రతను ఏర్పాటు చేసే వేగాన్ని మెరుగుపరుస్తుంది. ఈ ఆపరేషన్ కోలుకోలేనిది. చాలా సింగిల్ బోర్డ్ " -"కంప్యూటర్‌లలో దీనికి కొన్ని నిమిషాలు మాత్రమే పడుతుంది." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"%(box_name)sలో OpenVPN యొక్క అన్ని కొత్త ఇన్‌స్టాలేషన్‌లు డిఫాల్ట్‌గా ECCని ఉపయోగిస్తాయి. వీలైనంత త్వరగా " -"వలస వెళ్లాలని మేము సిఫార్సు చేస్తున్నాము." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"హెచ్చరిక: ఈ ఆపరేషన్ ద్వారా ఇప్పటికే ఉన్న క్లయింట్ ప్రొఫైల్‌లు చెల్లుబాటు కావు. %(box_name)sలోని " -"OpenVPN వినియోగదారులందరూ తప్పనిసరిగా వారి కొత్త ప్రొఫైల్‌లను డౌన్‌లోడ్ చేసుకోవాలి. ఈ సర్వర్‌కి కనెక్ట్ చేయడానికి " -"ECCకి అనుకూలమైన OpenVPN క్లయింట్‌లను ఉపయోగించాలి." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "మోడిగ్రేట్ చేయండి" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "స్థూల వివరం" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, fuzzy, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "బాక్స్_నామలు 1 యొక్క విపిన్ కనెక్ట్, మీరు ఒక ప్రొఫైల్ డౌన్లోడ్ మరియు మీ మొబైల్ లేదా డెస్క్టాప్ మిషన్పై ఓపెన్ప్ప్న్ " @@ -4890,16 +4830,17 @@ msgstr "" "2డాక్యుమెంటేషన్ &ల్టీ;/ఆ&జీత్; 3 టైటిల్=\"%బావీ క్స్_నామ ఆకృతీకరించుటకు ఎలా సిఫార్సు " "ఖాతాదారులకు మరియు సూచనలతో వాటిని. %(box_name)s" -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "ప్రొఫైల్ ప్రతి %(box_name)s వాడుకరికి నిర్ధిష్టమైనది. దాన్ని రహస్యంగా ఉంచండి." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "నా స్థూలవివరంల దిగుమతి" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4911,24 +4852,24 @@ msgstr "" "వ్యవస్థ. మీ {box_name} సేవలు మిగిలిన ఇంటర్నెట్‌లో అందుబాటులో లేనట్లయితే మాత్రమే మీకు ఇది అవసరం. ఇది " "క్రింది పరిస్థితులను కలిగి ఉంటుంది:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} పరిమితం చేయబడిన ఫైర్‌వాల్ వెనుక ఉంది." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "{box_name} మీరు నియంత్రించని (వైర్‌లెస్) రూటర్‌కి బందించబడింది ." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" "మీ ISP మీకు బాహ్య IP చిరునామాను అందించదు మరియు బదులుగా NAT ద్వారా ఇంటర్నెట్ కనెక్షన్‌ని అందిస్తుంది." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -4936,11 +4877,11 @@ msgstr "" "మీ ISP మీకు స్టాటిక్ IP చిరునామాను అందించదు మరియు మీరు ఇంటర్నెట్‌కి కనెక్ట్ అయిన ప్రతిసారీ మీ IP చిరునామా " "మారుతుంది." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "మీ ISP ఇన్‌కమింగ్ కనెక్షన్‌లను పరిమితం చేస్తుంది." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4953,23 +4894,23 @@ msgstr "" "\"https://pagekite.net\">pagekite.net. భవిష్యత్తులో దీని కోసం మీ స్నేహితుని " "{box_name}ని ఉపయోగించడం సాధ్యమవుతుంది." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "పేజ్‌కైట్" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "ప్రజా దృశ్యమానం" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "పేజ్‌కైట్ అధికారక్షేత్రం" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "సర్వర్ అధికారక్షేత్రం" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -4977,66 +4918,66 @@ msgstr "" "మీ పేజ్‌కైట్ సర్వర్‌ని ఎంచుకోండి. డిఫాల్ట్ pagekite.net సర్వర్‌ని ఉపయోగించడానికి \"pagekite.net\"ని సెట్ " "చేయండి." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "సర్వర్ పోర్ట్" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "మీ పేజ్‌కైట్ సర్వర్ యొక్క పోర్ట్ (డిఫాల్ట్: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "కైట్ పేరు" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "ఉదాహరణ: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "చెల్లని కైట్ పేరు" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "కైట్ రహస్యము" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" "గాలిపటంతో అనుబంధించబడిన రహస్యం లేదా గాలిపటంపై రహస్యం ఏదీ సెట్ చేయకుంటే మీ ఖాతా కోసం డిఫాల్ట్ రహస్యం." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "ప్రోటోకాల్" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "బాహ్య (ఫ్రంటెండ్) పోర్ట్" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "అంతర్గత (ఫ్రీడమ్బాక్స్) పోర్ట్" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "సబ్డొమైన్లు క్రియాశీలీకరించు" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "కస్టమ్ సర్వీస్ తొలగించబడింది" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "ఈ సేవ ఇప్పటికే ప్రామాణిక సేవగా అందుబాటులో ఉంది." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "అనుకూల సేవ జోడించబడింది" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "ఈ సేవ ఇప్పటికే ఉంది" @@ -5072,29 +5013,29 @@ msgstr "" "హెచ్చరిక:
మా PageKite ఫ్రంటెండ్ సర్వర్ మీరు ఇక్కడ నిర్వచించే చేయగల అన్ని ప్రోటోకాల్ / పోర్ట్ " "కాంబినేషన్ మద్దతు ఇవ్వకపోవచ్చు. ఉదాహరణకు, HTTPS 443 పోర్ట్లకు సమస్యలు కారణమవుతుంది." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "వెబ్ సేవిక (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "సైట్ http://{0} వద్ద అందుబాటులో ఉంటుంది" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "వెబ్ సేవిక (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "సైట్ https://{0} వద్ద అందుబాటులో ఉంటుంది" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "సెక్యూర్ షెల్ (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5143,8 +5084,8 @@ msgstr "" "ప్రస్తుతం సంస్థాపన లేదా నవీకరణ నడుస్తోంది. మూసివేయడానికి లేదా పునఃప్రారంభించడానికి ముందు ఇది పూర్తి " "అయ్యే వరకు వేచి ఉండండి." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "పునఃప్రారంభించండి" @@ -5193,6 +5134,39 @@ msgstr "" msgid "Shut Down Now" msgstr "ఇపుడు మూసివేయండి" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "ప్రివొక్సి" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5237,7 +5211,7 @@ msgstr "వెబ్ ప్రాక్సీ" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "టీసీపీ{kind} పై{proxy} తో యాక్సిస్ {url} చేయండి" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5253,7 +5227,7 @@ msgstr "" "అమలు చేయగలదు మరియు డెస్క్‌టాప్ లేదా మొబైల్ నుండి ఒకటి లేదా అంతకంటే ఎక్కువ క్వాసెల్ క్లయింట్‌లను కనెక్ట్ " "చేయడానికి మరియు డిస్‌కనెక్ట్ చేయడానికి ఉపయోగించవచ్చు." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your మొబైల్ పరికరాలు అందుబాటులో " "ఉన్నాయి." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "క్వాసెల్" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC క్లయింట్" @@ -5277,7 +5251,7 @@ msgstr "IRC క్లయింట్" msgid "Quasseldroid" msgstr "క్వాసెల్ డ్రొఇడ్" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, fuzzy, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5291,7 +5265,7 @@ msgstr "" "\"&జిత్ ;మద్దతు ఉన్న క్లయింట్ అప్లికేషన్&ల్టీ ;/ఆ &జిత్; అవసరం.\n" "రాడికల్ ఏ యూజర్ అయినా బాక్స్_నామలాగిన్ తో యాక్సెస్ చేయవచ్చు {box_name}" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5301,12 +5275,12 @@ msgstr "" "రూపొందించడానికి మాత్రమే మద్దతు ఇస్తుంది. ఈవెంట్‌లు లేదా పరిచయాలను జోడించడానికి ఇది మద్దతు ఇవ్వదు, ఇది " "ప్రత్యేక క్లయింట్‌ని ఉపయోగించి చేయాలి." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "రాడికేల్" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "క్యాలెండర్ మరియు అడ్రస్సు పుస్తకము" @@ -5378,7 +5352,7 @@ msgstr "" "శోధన బటన్‌పై క్లిక్ చేయడం ద్వారా ఇప్పటికే ఉన్న క్యాలెండర్‌లు మరియు చిరునామా పుస్తకాలు జాబితా చేయబడతాయి." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "సాంగత్యం హక్కుల కాన్ఫిగరేషన్ నవీకరించబడింది" @@ -5464,7 +5438,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "న్యూస్ ఫీడ్‌లను చదవడం మరియు చందాదారునిగా చేరు" @@ -5477,7 +5451,7 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5485,7 +5459,7 @@ msgstr "" "మీ స్థానిక నెట్‌వర్క్‌లోని ఫ్రీడమ్‌బాక్స్ మరియు ఇతర కంప్యూటర్ల మధ్య ఫైల్‌లు మరియు ఫోల్డర్‌లను పంచుకోవడానికి సాంబా " "అనుమతిస్తుంది." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5497,11 +5471,11 @@ msgstr "" "కంప్యూటర్‌లోని ఫైల్ మేనేజర్‌లో \\\\{hostname} (Windowsలో) లేదా smb://{hostname}.local " "(Linux మరియు Macలో) వద్ద యాక్సెస్ చేయవచ్చు. మీరు ఎంచుకోగల మూడు రకాల షేర్లు ఉన్నాయి: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "ఓపెన్ షేర్ - మీ స్థానిక నెట్‌వర్క్‌లోని ప్రతి ఒక్కరికీ అందుబాటులో ఉంటుంది." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5509,7 +5483,7 @@ msgstr "" "గ్రూప్ షేర్ - freedombox-share గ్రూపులో ఉన్న ఫ్రీడమ్‌బాక్స్ వినియోగదారులకు మాత్రమే అందుబాటులో " "ఉంటుంది." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5517,15 +5491,15 @@ msgstr "" "హోమ్ షేర్ - freedombox-share గ్రూపులో ఉన్న ప్రతి వినియోగదారుడు వారి స్వంత ప్రైవేట్ స్థలాన్ని కలిగి " "ఉంటారు." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "ప్రైవేటు షేర్లలో ప్రవేశం" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "సాంబా" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "నెట్‌వర్క్ దస్త్రంనిల్వ" @@ -5614,15 +5588,15 @@ msgstr "భాగస్వామ్యం పేరు" msgid "Action" msgstr "చర్య" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "ఫ్రీడమ్‌బాక్స్ OS డిస్క్" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "భాగస్వామ్యాన్ని తెరవండి" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "సమూహం భాగస్వామ్యం" @@ -5648,7 +5622,7 @@ msgstr "భాగస్వామ్యం నిలిపివేయబడి msgid "Error disabling share: {error_message}" msgstr "భాగస్వామ్యాన్ని నిలిపివేయడంలో లోపం: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5656,7 +5630,7 @@ msgstr "" "సెర్క్స్ అనేది గోప్యతను గౌరవించే ఒక మెటా-శోధన ఇంజిన్. ఇది బహుళ శోధన ఇంజిన్ల నుండి ఫలితాలను సమీకరించి, " "ప్రదర్శిస్తుంది." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5664,39 +5638,39 @@ msgstr "" "శోధన యంత్రాలు ద్వారా ట్రాకింగ్ మరియు ప్రొఫైలింగ్ను నివారించడానికి సెర్క్స్ ను ఉపయోగించవచ్చు. ఇది మాములుగా " "కుకీలను నిల్వ ఉంచుకోదు." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "అంతర్జాలమును శోధింపుము" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "సేర్క్స్" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "వెబ్ శోధన" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "సురక్షితశోధన" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "మీ శోధన ఫలితాలపైన అమలు చేయబడే కుటుంబ వడపోత విధానమును ఎంచుకొనండి." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "మితమైన" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "కఠినమైన" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "ప్రజా ప్రాప్తి అనుమతించు" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "ఈ అనువర్తనాన్ని చేరుకోగల ఎవరైనా ఉపయోగించడానికి అనుమతించండి." @@ -5870,7 +5844,7 @@ msgstr "బుక్‌మార్క్‌లు" msgid "Shaarlier" msgstr "షార్లియర్" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -5879,7 +5853,7 @@ msgstr "" "షాడోసాక్స్ మీ ఇంటర్నెట్ ట్రాఫిక్ను రక్షించేందుకు రూపొందించబడిన ఒక తేలికైన మరియు సురక్షిత సాక్స్5 ప్రాక్సీ. " "ఇది ఇంటర్నెట్ వడపోత మరియు సెన్సార్షిప్ను దాటడానికి ఉపయోగించవచ్చు." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5891,7 +5865,7 @@ msgstr "" "చేయగలదు. ఇది SOCKS5 ప్రాక్సీని కూడా అమలు చేస్తుంది. స్థానిక పరికరాలు ఈ ప్రాక్సీకి కనెక్ట్ చేయగలవు " "మరియు వాటి డేటా Shadowsocks సర్వర్ ద్వారా గుప్తీకరించబడుతుంది మరియు ప్రాక్సీ చేయబడుతుంది." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -5899,40 +5873,40 @@ msgstr "" "సెటప్ తర్వాత Shadowsocksని ఉపయోగించడానికి, మీ పరికరం, బ్రౌజర్ లేదా అప్లికేషన్‌లో SOCKS5 ప్రాక్సీ URLని " "http://freedombox_address:1080/కి సెట్ చేయండి" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "షాడోసాక్స్" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "సాక్స్5 ప్రాక్సీ" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "సిఫార్సు చేయబడింది" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "సర్వర్" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "సర్వర్ హోస్ట్ పేరు లేదా ఐపి చిరునామా" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "సర్వర్ పోర్ట్ సంఖ్య" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "సమాచారాన్ని గుప్తీకరించాడానికి ఉపయోగించబడిన పాస్వర్డ్. తప్పకుండ సర్వర్ పాస్వర్డ్ తో సరిపోలాలి." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "గుప్తీకరించు పద్దతి. సర్వర్ లోని సెట్టింగ్‌తో సరిపోలాలి." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -5941,51 +5915,51 @@ msgstr "" "వెబ్‌లో ఎంచుకున్న వినియోగదారుల సమూహాలతో మీ {box_name}లోని ఫైల్‌లు మరియు ఫోల్డర్‌లను భాగస్వామ్యం చేయడానికి " "భాగస్వామ్యం మిమ్మల్ని అనుమతిస్తుంది." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "భాగస్వామ్యం" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "షేర్ యొక్క పేరు" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "ప్రత్యేకంగా ఒక వాటాను గుర్తించే చిన్న అక్షర సంఖ్యా స్ట్రింగ్. ఉదాహరణ: media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "షేర్ యొక్క మార్గం" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "ఈ సర్వర్ పైన మీరు పంచుకోవాలి అనుకుంటున్న ఫోల్డర్ యొక్క డిస్క్ మార్గం." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "ప్రజా వాటా" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "ఈ ఫోల్డర్‌లోని ఫైల్‌లను లింక్ ఉన్న ఎవరికైనా అందుబాటులో ఉంచండి." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "భాగస్వామ్యంలోని ఫైళ్లను చదవగలిగే వినియోగదారుల సమూహాలు:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "ఎంచుకున్న వినియోగదారు సమూహాల వినియోగదారులు షేర్‌లోని ఫైల్‌లను చదవగలరు." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "ఈ పేరుతో ఒక వాటా ఇప్పటికే ఉంది." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "షేర్లు పబ్లిక్ గా ఉండాలి లేదా కనీసం ఒక గ్రూపుతో పంచుకోవాలి" @@ -6022,19 +5996,19 @@ msgstr "పంచుకోబడ్డ" msgid "Add Share" msgstr "వాటా జోడించండి" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "భాగస్వామ్యం సవరించబడింది." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "భాగస్వామ్యాన్ని సవరించండి" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "వాటా తొలగించబడింది." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6044,7 +6018,7 @@ msgstr "" "అవాంఛిత మార్పులు సంభవించినప్పుడు సిస్టమ్‌ను గతంలో తెలిసిన మంచి స్థితికి రోల్ బ్యాక్ చేయడానికి వీటిని " "ఉపయోగించవచ్చు." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6054,7 +6028,7 @@ msgstr "" "స్నాప్‌షాట్‌లు క్రమానుగతంగా తీసుకోబడతాయి (టైమ్‌లైన్ స్నాప్‌షాట్‌లు అని పిలుస్తారు) మరియు సాఫ్ట్‌వేర్ ఇన్‌స్టాలేషన్‌కు " "ముందు మరియు తర్వాత కూడా. దిగువ సెట్టింగ్‌ల ప్రకారం పాత స్నాప్‌షాట్‌లు స్వయంచాలకంగా శుభ్రం చేయబడతాయి." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for బ్యాకప్‌లకి ప్రత్యామ్నాయం కాదు, ఎందుకంటే అవి ఒకే విభజనలో " "మాత్రమే నిల్వ చేయబడతాయి. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "నిల్వ దృశ్యములు" @@ -6161,7 +6135,7 @@ msgstr "తేదీ" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "స్నాప్షాట్‌లను తొలగించు" @@ -6213,57 +6187,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "స్నాప్షాట్ #%(number)s కు రోల్‌బ్యాక్ చేయండి" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "మానవీయంగా సృష్టించబడింది" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "కాలక్రమం" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "సముచితమైనది" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "స్నాప్‌షాట్‌లను నిర్వహించండి" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "స్నాప్షాట్‌ సృష్టించబడినది." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "నిల్వ స్నాప్‌షాట్‌ల కాన్ఫిగరేషన్ నవీకరించబడింది" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "చర్య లోపం:{0}{1}{2}" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "ఎంచుకున్న స్నాప్‌షాట్‌లు తొలగించబడ్డాయి" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "స్నాప్‌షాట్ ప్రస్తుతం వాడుకలో ఉంది. దయచేసి తర్వాత మళ్లీ ప్రయత్నించండి." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "స్నాప్షాట్ #{number} కు తీస్కుని వెళ్ళబడింది." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "రొల్ల్బచ్క్ ని పూర్తి చేయడానికి వ్యవస్థను పునరుద్ధరించాలి." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "చాయాచిత్రం కు రొల్ల్బచ్క్ చేయండి" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6274,7 +6248,7 @@ msgstr "" "ఉపయోగిస్తుంది. అధీకృత రిమోట్ కంప్యూటర్ అటువంటి కనెక్షన్‌లను ఉపయోగించి అడ్మినిస్ట్రేషన్ పనులను చేయగలదు, " "ఫైల్‌లను కాపీ చేయగలదు లేదా ఇతర సేవలను అమలు చేయగలదు." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "సెక్యూర్ షెల్ (SSH) సర్వర్" @@ -6311,14 +6285,6 @@ msgstr "అల్గారిథం" msgid "Fingerprint" msgstr "వేలిముద్ర" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "SSH ప్రమాణీకరణ తో SSH ఆపివేయబడింది ." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "SSH ప్రమాణీకరణ తో SSH ఆపివేయబడింది ." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "సింగిల్ సైన్ ఆన్" @@ -6331,7 +6297,7 @@ msgstr "ప్రవేశించు" msgid "Logged out successfully." msgstr "విజయవంతంగా లాగ్ అవుట్ చేయబడింది." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6342,104 +6308,104 @@ msgstr "" "ప్రస్తుతం వాడుకలో ఉన్న స్టోరేజ్ మీడియాను వీక్షించవచ్చు, తొలగించగల మీడియాను మౌంట్ చేయవచ్చు మరియు అన్‌మౌంట్ " "చేయవచ్చు, రూట్ విభజనను విస్తరించవచ్చు మొదలైనవి." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "నిల్వ" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} బైట్లు" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} కిలోబైట్లు" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} మెగాబైట్లు" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} గిగాబైట్లు" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} టెరాబైట్లు" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "ఆపరేషన్ విఫలమైంది." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "ఆపరేషన్ రద్దు చేయబడింది." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "పరికరం ఇప్పటికే అన్‌మౌంట్ చేయబడుతోంది." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "డ్రైవర్/టూల్ సపోర్ట్ తప్పిపోయినందున ఆపరేషన్‌కు మద్దతు లేదు." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "ఆపరేషన్ టైమవుట్ అయింది." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "ఈ ఆపరేషన్ గాఢ నిద్రలో ఉన్న ఒక డిస్క్ ను మేల్కొలుపుతుంది." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "బిజీగా ఉన్న పరికరాన్ని అన్‌మౌంట్ చేయడానికి ప్రయత్నిస్తోంది." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "ఆపరేషన్ ఇప్పటికే రద్దు చేయబడింది." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "అభ్యర్థించిన ఆపరేషన్ చేయడానికి అధికారం లేదు." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "పరికరం ఇప్పటికే మౌంట్ చేయబడింది." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "పరికరం మౌంట్ చేయబడలేదు." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "అభ్యర్థించిన ఎంపికను ఉపయోగించడానికి అనుమతి లేదు." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "పరికరం మరొక వినియోగదారుచే మౌంట్ చేయబడింది." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "సిస్టమ్ విభజనలో తక్కువ స్థలం: {percent_used}% used, {free_space} ఉచితం." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "తక్కువ ఖని స్థలం" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "ఖని వైఫల్యం ఆసన్నమైంది" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6448,39 +6414,39 @@ msgstr "" "ఖని {id}సమీప భవిష్యత్తులో విఫలమయ్యే అవకాశం ఉందని నివేదిస్తోంది. మీరు చేయగలిగినప్పుడు ఏదైనా సమాచారంకాపీ " "చేసి, చోదకం భర్తీ చేయండి." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "డైరెక్టరీ పేరు చెల్లదు." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "డైరెక్టరీ ఉనికిలో లేదు." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "మార్గం అనేది డైరెక్టరీ కాదు." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "వినియోగదారు ద్వారా డైరెక్టరీ చదవబడలేదు." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "వినియోగదారు ద్వారా డైరెక్టరీ వ్రాయబడలేదు." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "డైరెక్టరీ" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "ఉప డైరెక్టరీ (ఐచ్ఛికం)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "పంచుకోబడ్డ" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "ఇతర డైరెక్టరీ (దిగువన పేర్కొనండి)" @@ -6517,7 +6483,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "రూట్ విభజనను విస్తరించు" @@ -6539,30 +6505,30 @@ msgstr "" "దయచేసి మీ సమాచారాన్ని బ్యాకప్ (భద్రపరచు కొనుట) చేస్కోండి. ఈ క్రియ తర్వాత %(expandable_root_size)s " "అధనపు సామర్ధ్యం మీ రూ విభజనలో అందుబాటులోకి వస్తుంది." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "విభజన విస్తరణలో దోషం: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "విభజనను విస్తరించడం విజయవంతమైనది." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} ని సురక్షితంగా తొలగించవచ్చు." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "పరికరాన్ని సురక్షితంగా తొలగించవచ్చు." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "పరికరాన్ని తొలగించడంలో లోపం: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6573,7 +6539,7 @@ msgstr "" "మరియు మొబైల్ ఫోన్. ఒక పరికరంలో ఫైల్‌లను సృష్టించడం, సవరించడం లేదా తొలగించడం అనేది సమకాలీకరణను అమలు " "చేసే అన్ని ఇతర పరికరాలలో స్వయంచాలకంగా పునరావృతమవుతుంది." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6590,20 +6556,20 @@ msgstr "" "సెట్ ప్రత్యేక ఫోల్డర్‌ల సెట్‌తో సమకాలీకరించబడవచ్చు.వెబ్ ఇంటర్‌ఫేస్ ఆన్ చేయబడింది{box_name} నిర్వాహకుడు \" " "లేదా \"సమకాలీకరణ-యాక్సెస్\" సమూహానికి చెందిన వినియోగదారులకు మాత్రమే అందుబాటులో ఉంటుంది." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "సమకాలీకరణ అప్లికేషన్‌ను నిర్వహించండి" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "సింక్ తింగ్" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "ఫైళ్ళ సమకాలీకరణ" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6616,7 +6582,7 @@ msgstr "" "టార్ ప్రాజెక్ట్ మీరు టార్ బ్రౌజర్ ను ఉపయోగించాలని సిఫార్సు చేస్తున్నారు." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, fuzzy, python-brace-format #| msgid "A Tor SOCKS port is available on your %(box_name)s on TCP port 9050." msgid "" @@ -6624,40 +6590,40 @@ msgid "" "TCP port 9050." msgstr "టిసిపి పోర్ట్ 9050 పై ఒక టార్ సొక్స్ పోర్ట్ మీ %(box_name)sలో అందుబాటులో ఉంది." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "టార్" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "టోర్ ఉల్లిపాయ సేవ" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "టోర్ సాక్స్ ప్రాతినిధ్య" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "టార్ బ్రిడ్జ్ రిలే" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "టార్ రిలే పోర్ట్ అందుబాటులో ఉంది" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 రవాణా నమోదు చేయబడింది" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 రవాణా నమోదు చేయబడింది" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "టార్ ద్వారా {kind} లో {url} ను ఆక్సెస్ చెయ్యండి" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "టోర్ వాడుకను నిర్ధారించండి{url} టీ సి పి పై{kind}" @@ -6771,13 +6737,13 @@ msgstr "ఉల్లిపాయ సేవ" msgid "Ports" msgstr "పోర్ట్స్" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "అక్రుతీకరణలో ఒక పొరపాటు జరిగింది." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6835,7 +6801,7 @@ msgstr "" msgid "Transmission" msgstr "ట్రాన్స్మిషన్" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -6845,7 +6811,7 @@ msgstr "" "డెస్క్‌టాప్ అప్లికేషన్‌కు దగ్గరగా ఉన్నట్లు భావించేటప్పుడు ఏ ప్రదేశం నుండి అయినా వార్తలను చదవడానికి " "అనుమతించేలా రూపొందించబడింది." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "When enabled, Tiny Tiny RSS can be accessed by any {box_name} లాగిన్‌తో " "వినియోగదారు అయినా సాంగత్యం చేయవచ్చు." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -6865,11 +6831,11 @@ msgstr "" "చిన్న చిన్న RSS కోసం మొబైల్ లేదా డెస్క్‌టాప్ అప్లికేషన్‌ను ఉపయోగిస్తున్నప్పుడు, URLని ఉపయోగించండి/tt-rss-app కలపడం కోసం ." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "టైనీ టైనీ RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "న్యూస్ ఫీడ్ రీడర్" @@ -6877,12 +6843,12 @@ msgstr "న్యూస్ ఫీడ్ రీడర్" msgid "Tiny Tiny RSS (Fork)" msgstr "చిన్న చిన్న RSS (ఫోర్క్)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "తాజా సాఫ్ట్‌వేర్ మరియు భద్రత నవీకరణను కోసం తనిఖీ చేయండి మరియు వర్తించండి." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6894,22 +6860,22 @@ msgstr "" "అందుబాటులో ఉండవు. సిస్టమ్ రీబూట్ అవసరమని భావించినట్లయితే, అది స్వయంచాలకంగా 02:00కి చేయబడుతుంది, " "దీని వలన అన్ని యాప్‌లు క్లుప్తంగా అందుబాటులో ఉండవు." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "సాఫ్ట్‌వేర్ నవీకరణ" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "స్వతంత్ర సాఫ్ట్వేర్ తాజా పరుచడం" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "పంపిణీ నవీకరణను ప్రారంభించడం సాధ్యపడలేదు" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -6918,11 +6884,11 @@ msgstr "" "పంపిణీ నవీకరణను ప్రారంభించడానికి రూట్ విభజనలో తగినంత ఖాళీ స్థలం లేదు. దయచేసి కనీసం 5 GB ఉచితంగా " "ఉండేలా చూసుకోండి. ప్రారంభించబడితే, పంపిణీ నవీకరణ 24 గంటల తర్వాత మళ్లీ ప్రయత్నించబడుతుంది." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "పంపిణీ నవీకరణ ప్రారంభమైంది" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "తదుపరి స్థిరమైన విడుదలకు నవీకరణ ప్రారంభించబడింది. ఇది పూర్తి కావడానికి చాలా సమయం పట్టవచ్చు." @@ -7094,46 +7060,46 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "పంపిణీ మెరుగుపరుచడం ప్రారంభించబడింది" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "గమనింపబడని-నవీకరణలు ఆకృతీకరించునప్పుడు దోషం: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "స్వయంచాలక నవీకరణలు ప్రారంభించబడ్డాయి" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "స్వయంచాలక నవీకరణలు నిలిపివేయబడ్డాయి" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "పంపిణీ మెరుగుపరుచడం ప్రారంభించబడింది" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "పంపిణీ మెరుగుపరుచడం నిలిపివేయబడింది" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "అప్గ్రేడ్ ప్రక్రియ ప్రారంభించబడింది." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "నవీకరణ ప్రారంభం విఫలమైంది." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "తరచుగా ఫీచర్ అప్‌డేట్‌లు యాక్టివేట్ చేయబడ్డాయి." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 #, fuzzy #| msgid "Distribution upgrade enabled" msgid "Starting distribution upgrade test." msgstr "పంపిణీ మెరుగుపరుచడం ప్రారంభించబడింది" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7143,7 +7109,7 @@ msgstr "" "విధానంగా పనిచేస్తాయి. కొన్ని యాప్‌లకు యాప్‌ను యాక్సెస్ చేయడానికి వినియోగదారుని ప్రామాణీకరించడానికి సమూహంలో భాగంగా " "వినియోగదారు ఖాతా అవసరం" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7154,15 +7120,15 @@ msgstr "" "చేయవచ్చు. అయినప్పటికీ, అడ్మిన్ సమూహం యొక్క వినియోగదారులు మాత్రమే యాప్‌లు లేదా సిస్టమ్ " "సెట్టింగ్‌లను మార్చవచ్చు." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "వినియోగదారులు మరియు సమూహాలు" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "అన్ని సేవలకు మరియు సిస్టమ్ అమరికలకు ప్రాప్యత" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "LDAP నమోదు \"{search_item}\" తనిఖీ" @@ -7181,21 +7147,21 @@ msgid "" msgstr "" "అవసరం. 150 అక్షరాలు లేదా అంతకంటే తక్కువ. ఆంగ్ల అక్షరాలు, అంకెలు మరియు @/./-/_ మాత్రమే." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "అధికార రహస్యపదం" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "వినియోగదారు కోసం పాస్‌వర్డ్‌ను నమోదు చేయండి\"{user}\"ఖాతా సవరణలకు అధికారం ఇవ్వడానికి." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "చెల్లని రహస్యపదం." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7208,14 +7174,14 @@ msgstr "" "అన్ని సేవలకు లాగిన్ చేయగలరు. వారు SSH ద్వారా సిస్టమ్‌కి లాగిన్ అవ్వగలరు మరియు నిర్వాహక అధికారాలను (సూడో) " "కలిగి ఉంటారు." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" "ల్డప్ వినియోగదారుని సృష్టించడం విఫలమైంది.\n" ".: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, fuzzy, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "సమూహంసమూహానికి కొత్త వినియోగదారుని జోడించడంలో విఫలమైంది: {లోపం {group} {error}" @@ -7234,41 +7200,41 @@ msgstr "" "అవ్వడానికి అనుమతిస్తుంది. మీరు బహుళ కీలను నమోదు చేయవచ్చు, ఒక్కో లైన్‌లో ఒకటి. #తో ప్రారంభమయ్యే ఖాళీ " "పంక్తులు మరియు పంక్తులు విస్మరించబడతాయి." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "ఎల్.డి.ఏ.పి వాడుకరి పేరుమార్పులో విఫలం." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "సమూహంలోంచి వినియోగదారుని తొలగించడంలో విఫలం." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "సమూహంలోకి వినియోగదారుని జోడించడంలో విఫలం." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "SSH కీలను సెట్ చేయడం సాధ్యం కాలేదు." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "వినియోగదారు స్థితిని మార్చడంలో విఫలమైంది." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "ఎల్.డి.ఏ.పి వాడుకరి పాస్‌వర్డ్ మార్పిడి విఫలం." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "నిర్వాహక సమూహానికి కొత్త వినియోగదారుని జోడించడంలో విఫలమైంది: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "కన్సోల్ యాక్సెస్‌ని పరిమితం చేయడంలో విఫలమైంది: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "వాడుకరి ఖాతా సృస్టించబడింది, మీరు లాగిన్ చేయబడ్డారు" @@ -7285,12 +7251,12 @@ msgstr "పాస్‌వర్డ్‌ను సేవ్ చేయి" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "వినియోగదారుని సృష్టించు" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "వినియోగదారుని తొలగించు" @@ -7330,13 +7296,19 @@ msgid "The following administrator accounts exist in the system." msgstr "వ్యవస్థలో కింది నిర్వాహక ఖాతాలు ఉన్నాయి." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "కమాండ్ లైన్ నుండి ఈ ఖాతాలను తొలగించండి మరియు %(box_name)sతో ఉపయోగించగల ఖాతాను సృష్టించడానికి పేజీని " "రిఫ్రెష్ చేయండి. కమాండ్ లైన్‌లో 'echo \"{password}\" | ఆదేశాన్ని అమలు చేయండి /usr/share/plinth/" @@ -7344,7 +7316,7 @@ msgstr "" "ఉపయోగించగలిగితే, ఈ దశను దాటవేయండి." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "వినియోగదారులు" @@ -7377,34 +7349,34 @@ msgstr "" msgid "Save Changes" msgstr "మార్పులను భద్రపరుచు" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "వినియోగదారి %(username)s సృష్టించబడ్డారు." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "వినియోగదారి %(username)s నావీకరించబడ్డాడు." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "వినియోగదారి మార్పు" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "వినియోగదారి {user} తొలగించబడ్డాడు." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "ఎల్.డి.ఏ.పి వినియోగదారి తొలగింపు విఫలం." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "పాస్‌వర్డ్ మార్చు" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "పాస్‌వర్డ్ విజయవంతంగా మార్చబడినది." @@ -7732,7 +7704,7 @@ msgstr "సర్వర్‌కు కనెక్షన్‌ని తొల msgid "Server deleted." msgstr "సర్వర్ తొలగించబడింది." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7745,7 +7717,7 @@ msgstr "" "థీమ్‌లను ఉపయోగించి రూపాన్ని ఎంచుకోవచ్చు. అడ్మినిస్ట్రేషన్ ఇంటర్‌ఫేస్ మరియు ఉత్పత్తి చేయబడిన వెబ్ పేజీలు మొబైల్ " "పరికరాలకు అనుకూలంగా ఉంటాయి." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7758,7 +7730,7 @@ msgstr "" "చేయబడాలి. మీ పేజీలు మరియు పోస్ట్‌లకు మెరుగైన URLల కోసం అడ్మినిస్ట్రేటర్ ఇంటర్‌ఫేస్‌లో పెర్మాలింక్‌లను " "ప్రారంభించండి." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -7768,7 +7740,7 @@ msgstr "" "సృష్టించబడుతుంది. భవిష్యత్తులో అడ్మినిస్ట్రేషన్ ఇంటర్‌ఫేస్‌ను చేరుకోవడానికి అడ్మిన్ పేజీని బుక్‌మార్క్ చేయండి." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -7778,12 +7750,12 @@ msgstr "" "చేయాలి. అదనపు ప్లగిన్‌లు లేదా థీమ్‌లు మీ స్వంత పూచీతో ఇన్‌స్టాల్ చేయబడవచ్చు మరియు మెరుగుపరుచు " "చేయబడవచ్చు." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "వర్డుప్రెస్సు" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "వెబ్‌సైట్ మరియు బ్లాగ్" @@ -7799,7 +7771,7 @@ msgstr "" "సందర్శకులందరినీ అనుమతించండి. నిరుపయోగం చేయడం వలన వర్డుప్రెస్సు సైట్ లేదా బ్లాగును వీక్షించడానికి " "నిర్వాహకులు మాత్రమే అనుమతిస్తుంది. ప్రారంభ వర్డుప్రెస్సు సెటప్ చేసిన తర్వాత మాత్రమే ప్రారంభించండి." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7818,7 +7790,7 @@ msgstr "" "వీక్షణలను ఉపయోగించి ఒక వ్యక్తిని కలిగి ఉన్న అన్ని ఫోటోలు లేదా తేదీలో తీసిన ఫోటోలు లేదా ఒక ప్రదేశంలో తీసిన " "ఫోటోలను కనుగొనడం సులభం. డైరెక్ట్ లింక్‌ని పంపడం ద్వారా వ్యక్తిగత ఫోటోలను ఇతరులతో పంచుకోవచ్చు." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7828,11 +7800,11 @@ msgstr "" "జోఫ్ని సెటప్ చేసిన {box_name} వినియోగదారు కూడా Zophలో నిర్వాహకులు అవుతారు. అదనపు వినియోగదారుల " "కోసం, ఖాతాలు తప్పనిసరిగా {box_name}లో మరియు జోఫ్లో ఒకే వినియోగదారు పేరుతో సృష్టించబడాలి." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "జోఫ్" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "ఫోటో ఆర్గనైజర్" @@ -7885,116 +7857,110 @@ msgstr "" msgid "Finished: {name}" msgstr "సేవ నిలిపివేయబడింది: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "ప్యాకేజీ {package_name} తాజా వెర్షన్ ({latest_version})" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "బ్యాకప్ సమయంలో లోపం" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "వ్యవస్థాపిస్తోంది" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "దిగుమతి అవుతోంది" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "ప్రసార మాధ్యమం మార్పు" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "ఆకృతీకరణ ఫైలు: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 #, fuzzy #| msgid "Install Apps" msgid "Installing app" msgstr "అనువర్తనాలను నిక్షిప్తం చేద్దాం" -#: plinth/setup.py:42 +#: plinth/setup.py:43 #, fuzzy #| msgid "Updating..." msgid "Updating app" msgstr "నవీకరిస్తోంది." -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "అనువర్తనం స్థాపించుటలో దోషం: {string}{details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "అనువర్తనం స్థాపించుటలో దోషం: {string}{details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "అనువర్తనం స్థాపించుటలో దోషం: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "అనువర్తనం స్థాపించుటలో దోషం: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "అనువర్తనం స్థాపించబడింది." -#: plinth/setup.py:87 +#: plinth/setup.py:88 #, fuzzy #| msgid "Last update" msgid "App updated" msgstr "చివరి నవీకరణ" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Install Apps" msgid "Uninstalling app" msgstr "అనువర్తనాలను నిక్షిప్తం చేద్దాం" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "అనువర్తనం స్థాపించుటలో దోషం: {string}{details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "అనువర్తనం స్థాపించుటలో దోషం: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "అనువర్తనం స్థాపించబడింది." -#: plinth/setup.py:451 +#: plinth/setup.py:452 #, fuzzy #| msgid "Upgrade Packages" msgid "Updating app packages" @@ -8053,53 +8019,54 @@ msgstr "నిక్షిప్తం" msgid "Service %(service_name)s is not running." msgstr "%(service_name)s సేవ నడవడం లేదు." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "%(box_name)s కోసం కోర్ ఫంక్షనాలిటీ మరియు వెబ్ ఇంటర్‌ఫేస్" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " నివాసం" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "ముంగిలి" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " కార్యక్షేత్రం" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "అనువర్తనాలు" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " కార్యవ్యవస్థ" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "వ్యవస్థ" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "రహస్యపదాన్ని మార్చు" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "మూసివేయి" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "నిష్క్రమించు" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "బాషను ఎంచుకోండి" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "లోనికి ప్రవేశించండి" @@ -8385,6 +8352,74 @@ msgstr "" msgid "Gujarati" msgstr "గుజరాతీ" +#~ msgid "Enable DNSSEC" +#~ msgstr "DNSSEC అమలుచెయ్యి" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "డొమైన్ నేమ్ సిస్టం భద్రతా పొడిగింపు ని ప్రారంభించండి" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "ఫైర్‌వాల్ డెమోన్ రన్ కావడం లేదు. దయచేసి దీన్ని అమలు చేయండి. %(box_name)sలో ఫైర్‌వాల్ డిఫాల్ట్‌గా " +#~ "ప్రారంభించబడింది. ఏదైనా డెబియన్ ఆధారిత సిస్టమ్‌లో (%(box_name)s వంటివి) మీరు 'సర్వీస్ ఫైర్‌వాల్డ్ " +#~ "స్టార్ట్' కమాండ్‌ని ఉపయోగించి లేదా systemd 'systemctl start firewalld' ఉన్న సిస్టమ్ విషయంలో " +#~ "దీన్ని అమలు చేయవచ్చు." + +#~ msgid "Migrate to ECC" +#~ msgstr "ECCకి మైగ్రేట్ చేయండి" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "మీ OpenVPN ఇన్‌స్టాలేషన్ ప్రస్తుతం RSAని ఉపయోగిస్తోంది. ఆధునిక ఎలిప్టిక్ కర్వ్ క్రిప్టోగ్రఫీకి మారడం " +#~ "కనెక్షన్ మరియు భద్రతను ఏర్పాటు చేసే వేగాన్ని మెరుగుపరుస్తుంది. ఈ ఆపరేషన్ కోలుకోలేనిది. చాలా సింగిల్ " +#~ "బోర్డ్ కంప్యూటర్‌లలో దీనికి కొన్ని నిమిషాలు మాత్రమే పడుతుంది." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "%(box_name)sలో OpenVPN యొక్క అన్ని కొత్త ఇన్‌స్టాలేషన్‌లు డిఫాల్ట్‌గా ECCని ఉపయోగిస్తాయి. వీలైనంత " +#~ "త్వరగా వలస వెళ్లాలని మేము సిఫార్సు చేస్తున్నాము." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "హెచ్చరిక: ఈ ఆపరేషన్ ద్వారా ఇప్పటికే ఉన్న క్లయింట్ ప్రొఫైల్‌లు చెల్లుబాటు కావు. " +#~ "%(box_name)sలోని OpenVPN వినియోగదారులందరూ తప్పనిసరిగా వారి కొత్త ప్రొఫైల్‌లను డౌన్‌లోడ్ చేసుకోవాలి. ఈ " +#~ "సర్వర్‌కి కనెక్ట్ చేయడానికి ECCకి అనుకూలమైన OpenVPN క్లయింట్‌లను ఉపయోగించాలి." + +#~ msgid "Migrate" +#~ msgstr "మోడిగ్రేట్ చేయండి" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "SSH ప్రమాణీకరణ తో SSH ఆపివేయబడింది ." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "SSH ప్రమాణీకరణ తో SSH ఆపివేయబడింది ." + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "బ్యాకప్ సమయంలో లోపం" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "%(box_name)s కోసం కోర్ ఫంక్షనాలిటీ మరియు వెబ్ ఇంటర్‌ఫేస్" + #~ msgid "Network Connections" #~ msgstr "నెట్వర్క్ అనుసంధానాలు" diff --git a/plinth/locale/tr/LC_MESSAGES/django.po b/plinth/locale/tr/LC_MESSAGES/django.po index 92ecefd55..eaae6acff 100644 --- a/plinth/locale/tr/LC_MESSAGES/django.po +++ b/plinth/locale/tr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-14 17:19+0000\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1037,23 +1030,23 @@ msgstr "" "erişebilecektir. Erişimi olan tüm kullanıcılar tüm kütüphaneleri " "kullanabilir." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "calibre e-kitap kütüphanesini kullan" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "E-kitap Kütüphanesi" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Yeni kütüphanenin adı" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1061,7 +1054,7 @@ msgstr "" "Boşluklar veya özel karakterler olmadan sadece İngiliz alfabesi harfleri, " "sayılar ve _ . ve - karakterleri. Örnek: Kutuphanem_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Bu ada sahip bir kütüphane zaten var." @@ -1109,20 +1102,20 @@ msgstr "%(library)s kütüphanesine git" msgid "Delete library %(library)s" msgstr "%(library)s kütüphanesini sil" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Kütüphane oluşturuldu." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Kütüphane oluşturulurken bir hata meydana geldi." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} silindi." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "{name} silinemedi: {error}" @@ -1170,7 +1163,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Sunucu Yönetimi" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1178,18 +1171,18 @@ msgstr "" "Burada anamakine adı, etki alanı adı, web sunucusu ana sayfası vb. gibi bazı " "genel yapılandırma seçeneklerini ayarlayabilirsiniz." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Genel Yapılandırma" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Yapılandır" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1304,47 +1297,47 @@ msgstr "" "Günlükler, sisteme kimin eriştiği ve çeşitli hizmetlerden gelen hata " "ayıklama bilgileri hakkında bilgiler içerir" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Anamakine adı ayarlanırken hata oldu: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Anamakine adı ayarlandı" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Etki alanı adı ayarlanırken hata oldu: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Etki alanı adı ayarlandı" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Web sunucusu ana sayfası ayarlanırken hata oldu: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Web sunucusu ana sayfası ayarlandı" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Gelişmiş kip değiştirilirken hata oldu: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Gelişmiş uygulamalar ve özellikler gösteriliyor" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Gelişmiş uygulamalar ve özellikler gizleniyor" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1356,7 +1349,7 @@ msgstr "" "SIP ve diğer iletişim sunucuları, başka şekilde birbirleriyle bağlantı " "kuramayan taraflar arasında bir çağrı kurmak için bunu kullanabilir." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse veya ejabberd gibi " "sunucuların burada sağlanan ayrıntılarla yapılandırılması gerekir." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP Yardımcısı" @@ -1428,11 +1421,11 @@ msgstr "Saat dilimi ayarlanırken hata oldu: {exception}" msgid "Time zone set" msgstr "Saat dilimi ayarlandı" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge, bir Web kullanıcı arayüzüne sahip bir BitTorrent istemcisidir." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1440,16 +1433,16 @@ msgstr "" "Varsayılan parola 'deluge'dir, ancak bu hizmeti etkinleştirdikten hemen " "sonra oturum açmalı ve parolayı değiştirmelisiniz." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "BitTorrent uygulamalarını kullanarak dosyaları indir" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent Web İstemcisi" @@ -1576,7 +1569,7 @@ msgstr "Sonuç" msgid "Diagnostic Test" msgstr "Tanı Denemesi" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1588,7 +1581,7 @@ msgstr "" "başkalarının bu {box_name} tarafından sağlanan hizmetleri bulmasını " "engelleyecektir." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1605,7 +1598,7 @@ msgstr "" "sunucu DNS adınızı yeni IP'ye atayacaktır ve İnternet'ten birisi sizin DNS " "adınızı sorarsa, şu anki IP adresinizle bir yanıt alacaktır." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1618,11 +1611,11 @@ msgstr "" "freedns.afraid." "org adresinde bulabilirsiniz." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Değişken DNS İstemcisi" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Değişken Etki Alanı Adı" @@ -1751,7 +1744,7 @@ msgstr "Bu alan gereklidir." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1806,7 +1799,7 @@ msgstr "Sunucu bağlantıyı reddetti" msgid "Already up-to-date" msgstr "Zaten güncel" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1814,7 +1807,7 @@ msgstr "" "XMPP, açık ve standartlaştırılmış bir iletişim protokolüdür. Burada ejabberd " "adı verilen XMPP sunucunuzu çalıştırabilir ve yapılandırabilirsiniz." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client{box_name} oturum " "açma adı ile herhangi bir kullanıcı tarafından erişilebilir." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn uygulamasını yükleyin veya harici " "bir sunucu yapılandırın." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Sohbet Sunucusu" @@ -1970,7 +1963,7 @@ msgstr "" "Etki alanınızı sistemde Yapılandır sayfasında " "ayarlayabilirsiniz." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " @@ -1980,7 +1973,7 @@ msgstr "" "Postfix e-posta gönderir ve alır. Dovecot, e-posta istemcilerinin IMAP ve " "POP3 kullanarak posta kutunuza erişmesini sağlar. Rspamd spam ile ilgilenir." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1992,7 +1985,7 @@ msgstr "" "giden e-postaları da kısıtlar. Bazıları, açık bir istekten sonra kısıtlamayı " "kaldırır. Daha fazla bilgi için kılavuz sayfasına bakın." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -2007,7 +2000,7 @@ msgstr "" "ekleyebilirler. \"Postmaster\" gibi gerekli kod adları, ilk yönetici " "kullanıcıyı işaret ederek otomatik olarak oluşturulur." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -2015,7 +2008,7 @@ msgstr "" "Roundcube uygulaması, kullanıcıların " "e-postaya erişmesi için web arayüzü sağlar." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2145,7 +2138,7 @@ msgstr "Bağlantı noktası" msgid "Host/Target/Value" msgstr "Anamakine/Hedef/Değer" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2157,7 +2150,7 @@ msgstr "" "ve uygun şekilde yapılandırılmış halde tutulması, İnternet kaynaklı güvenlik " "tehdidi riskini azaltır." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Güvenlik Duvarı" @@ -2177,53 +2170,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Harici ağlar için {name} ({details}) bağlantı noktası kullanılamaz" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"Güvenlik duvarı arka plan programı çalışmıyor. Lütfen çalıştırın. Güvenlik " -"duvarı varsayılan olarak %(box_name)s ile etkinleştirilmiş gelir. Herhangi " -"bir Debian tabanlı sistemde (%(box_name)s gibi), 'service firewalld start' " -"komutunu kullanarak veya systemd 'systemctl start firewalld' olan bir sistem " -"durumunda çalıştırabilirsiniz." - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Hizmet/Bağlantı Noktası" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Etkinleştirildi" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Etkisizleştirildi" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "İzin Verildi" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "İzin Verildi (sadece dahili)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "İzin Verildi (sadece harici)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Engellendi" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2233,13 +2212,13 @@ msgstr "" "buna güvenlik duvarında da izin verilir ve bir hizmeti " "etkisizleştirdiğinizde, güvenlik duvarında da etkisizleştirilir." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Gelişmiş" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2293,7 +2272,7 @@ msgstr "Kurulumu Başlat" msgid "Setup Complete" msgstr "Kurulum Tamamlandı" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2311,7 +2290,7 @@ msgstr "" "depoları çoğaltabilir ve kod değişikliklerini yükleyebilirsiniz. Ve kodunuzu " "dünyanın her yerinden insanlarla paylaşabilirsiniz." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2319,68 +2298,68 @@ msgstr "" "Git'in nasıl kullanılacağı hakkında daha fazla bilgi edinmek için Git öğreticisini ziyaret edin." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Git depolarına okuma-yazma erişimi" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Basit Git Barındırma" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Geçersiz depo URL'si." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Geçersiz depo adı." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Varolan bir depoyu içe aktarmak için yeni bir deponun veya URL'nin adı." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Deponun açıklaması" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Gitweb'de görüntülemek için isteğe bağlı." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Depo sahibinin adı" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Özel depo" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Sadece yetkili kullanıcıların bu arşive erişmesine izin verir." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Bu ada sahip bir depo zaten var." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Deponun adı" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Bir depoyu benzersiz şekilde tanımlayan alfa sayısal bir dizgi." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Varsayılan dal" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb bunu varsayılan dal olarak görüntüler." @@ -2424,19 +2403,19 @@ msgstr "%(name)s Git Deposunu Sil" msgid "Delete this repository permanently?" msgstr "Bu depo kalıcı olarak silinsin mi?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Depo oluşturuldu." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Depo oluşturulurken bir hata meydana geldi." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Depo düzenlendi." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Depoyu düzenle" @@ -2797,7 +2776,7 @@ msgstr "{box_name} Hakkında" msgid "{box_name} Manual" msgstr "{box_name} Kılavuzu" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2809,7 +2788,7 @@ msgstr "" "olarak işletilen bir ağ aracılığıyla şifreli trafik göndererek isim " "gizliliği sağlar." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2817,26 +2796,26 @@ msgstr "" "I2P hakkında daha fazla bilgiyi proje ana sayfasında bulabilirsiniz." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" "Sağlanan web arayüzüne ilk ziyaret, yapılandırma işlemini başlatacaktır." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "I2P uygulamasını yönet" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "İsim Gizliliği Ağı" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P Vekil Sunucusu" @@ -2882,7 +2861,7 @@ msgstr "" "uygulama sağlar. Dosyaları torrent'leri ekleyerek indirin veya bir dosyayı " "paylaşmak için yeni bir torrent oluşturun." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2892,7 +2871,7 @@ msgstr "" "birkaç hafif biçimlendirme dilini, yorumlar ve RSS bildirimleri gibi ortak " "blog oluşturma işlevselliğini destekler." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2906,15 +2885,15 @@ msgstr "" "href=\"{users_url}\">Kullanıcı Yapılandırmasında bu izinleri " "değiştirebilir veya yeni kullanıcılar ekleyebilirsiniz." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Viki ve Blog" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Viki uygulamalarını görüntüle ve düzenle" @@ -2970,43 +2949,43 @@ msgstr "" "Bu eylem düzeltim geçmişi dahil olmak üzere tüm yazıları, sayfaları ve " "yorumları silecek. Bu viki ya da blog kalıcı olarak silinsin mi?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "{name} viki oluşturuldu." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Viki oluşturulamadı: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "{name} blog oluşturuldu." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Blog oluşturulamadı: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} silindi." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "{title} silinemedi: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" "infinoted, işbirliğine dayalı bir metin düzenleyici olan Gobby için bir " "sunucudur." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -3017,11 +2996,11 @@ msgstr "" "istemcisini indirin ve yükleyin. Ardından Gobby'yi başlatın, \"Sunucuya " "Bağlan\" seçeneğini seçin ve {box_name} cihazınızın etki alanı adını girin." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby Sunucusu" @@ -3069,7 +3048,7 @@ msgstr "Janus Video Odası" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "JavaScript lisans bilgileri" @@ -3089,7 +3068,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Sohbet İstemcisi" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3105,7 +3084,7 @@ msgstr "" "(CA) olan Let's Encrypt'a bir etki alanının sahibi olduğunu kanıtlayarak " "yapar." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -3117,15 +3096,15 @@ msgstr "" "Lütfen bu hizmeti kullanmadan önce Let's Encrypt Abone Sözleşmesini okuyun ve kabul edin." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Sertifikalar" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Denenemiyor: Hiçbir etki alanı yapılandırılmamış." @@ -3190,7 +3169,7 @@ msgstr "" "Hiçbir etki alanı yapılandırılmadı. Bunlar için sertifika alabilmek amacıyla " "etki alanlarını yapılandırın." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3199,34 +3178,34 @@ msgstr "" "{domain} etki alanı için sertifika başarılı olarak iptal edildi. Bunun " "etkili olması birkaç dakika alabilir." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "{domain} etki alanı için sertifika iptal etme başarısız oldu: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "{domain} etki alanı için sertifika başarılı olarak elde edildi" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "{domain} etki alanı için sertifika elde etme başarısız oldu: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "{domain} etki alanı için sertifika başarılı olarak silindi" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "{domain} etki alanı için sertifika silme başarısız oldu: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3243,7 +3222,7 @@ msgstr "" "kullanıcılar, federasyon aracılığıyla diğer tüm Matrix sunucularındaki " "kullanıcılarla sohbet edebilir." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3253,7 +3232,7 @@ msgstr "" "ihtiyaç duyar. Coturn uygulamasını yükleyin veya " "harici bir sunucu yapılandırın." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3360,7 +3339,7 @@ msgstr "" "sertifikası gerekir. Bir tane edinmek için lütfen Let's Encrypt'a gidin." -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3373,7 +3352,7 @@ msgstr "" "barındırmak, notlar almak veya projelerde arkadaşlarınızla işbirliği yapmak " "için kullanabilirsiniz." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3388,7 +3367,7 @@ msgstr "" "giderek MediaWiki'nin kendisinden daha fazla kullanıcı hesabı " "oluşturabilirsiniz." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3396,12 +3375,12 @@ msgstr "" "Bu viki'ye bağlantısı olan herkes bunu okuyabilir. Sadece oturum açmış " "kullanıcılar içerikte değişiklik yapabilir." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Viki" @@ -3483,35 +3462,35 @@ msgstr "Parola güncellendi" msgid "Password update failed. Please choose a stronger password" msgstr "Parola güncelleme başarısız oldu. Lütfen daha güçlü bir parola seçin" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Herkese açık kayıtlar etkinleştirildi" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Herkese açık kayıtlar etkisizleştirildi" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Özel kip etkinleştirildi" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Özel kip etkisizleştirildi" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Varsayılan kaplama değiştirildi" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Etki alanı adı güncellendi" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Site adı güncellendi" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3524,11 +3503,11 @@ msgstr "" "(30000) çalıştırılmasını sağlar. Sunucuya bağlanmak için bir Minetest istemcisi gereklidir." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Blok Kum Havuzu" @@ -3580,7 +3559,7 @@ msgstr "" msgid "Address" msgstr "Adres" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3767,7 +3746,7 @@ msgstr "Güvenli Kabuk" msgid "Services" msgstr "Hizmetler" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3775,7 +3754,7 @@ msgstr "" "Ağ cihazlarını yapılandırın. İnternet'e Ethernet, Wi-Fi veya PPPoE ile " "bağlanın. Bu bağlantıyı ağdaki diğer cihazlarla paylaşın." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3783,7 +3762,7 @@ msgstr "" "Diğer yöntemler aracılığıyla yönetilen cihazlar burada yapılandırma için " "mevcut olmayabilir." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Ağlar" @@ -4217,7 +4196,7 @@ msgstr "Bağlantıyı düzenle" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Düzenle" @@ -4322,7 +4301,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Yöntem" @@ -4338,7 +4317,7 @@ msgstr "DNS sunucusu" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Varsayılan" @@ -4351,7 +4330,7 @@ msgid "This connection is not active." msgstr "Bu bağlantı etkin değil." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Güvenlik" @@ -4934,7 +4913,7 @@ msgstr "{name} bağlantısı silindi." msgid "Failed to delete connection: Connection not found." msgstr "Bağlantının silinmesi başarısız oldu: Bağlantı bulunamadı." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4951,20 +4930,20 @@ msgstr "" "isim gizliliği sayesinde {box_name} aracılığıyla İnternet'e de " "erişebilirsiniz." -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "VPN hizmetlerine bağlan" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Sanal Özel Ağ" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4974,57 +4953,21 @@ msgstr "Profili İndir" msgid "Tunnelblick" msgstr "Tunnelblick" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "ECC'ye Geçir" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" -"OpenVPN kurulumunuz şu anda RSA kullanıyor. Modern Eliptik Eğri " -"Şifrelemesine geçiş, bağlantı kurma hızını ve güvenliği artırır. Bu işlem " -"geri alınamaz. Çoğu tek kartlı bilgisayarda sadece birkaç dakika sürmektedir." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" -"%(box_name)s cihazındaki tüm yeni OpenVPN kurulumları, varsayılan olarak " -"ECC'yi kullanacaktır. Mümkün olan en kısa sürede geçiş yapmanızı öneririz." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" -"Uyarı: Varolan istemci profilleri bu işlem tarafından geçersiz " -"kılınacaktır. %(box_name)s cihazındaki tüm OpenVPN kullanıcıları yeni " -"profillerini indirmek zorundadır. Bu sunucuya bağlanmak için ECC ile uyumlu " -"OpenVPN istemcileri kullanılmalıdır." - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "Geçir" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Profil" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "%(box_name)s cihazının VPN'ine bağlanmak için bir profil indirmeniz ve bunu " @@ -5033,16 +4976,17 @@ msgstr "" "bunların nasıl yapılandırılacağıyla ilgili talimatlar için yukarıdaki \"Daha " "fazla bilgi edinin...\" bağlantısına tıklayın." -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "Profil, %(box_name)s cihazının her kullanıcısına özgüdür. Gizli tutun." -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Profilimi indir" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -5055,17 +4999,17 @@ msgstr "" "{box_name} hizmetlerinize İnternet'ten erişilemiyorsa ihtiyacınız vardır. " "Bu, aşağıdaki durumları içerir:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} kısıtlanmış bir güvenlik duvarının arkasında." -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "{box_name} denetleyemediğiniz bir (kablosuz) yönlendiriciye bağlı." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -5073,7 +5017,7 @@ msgstr "" "İSS'niz size bir dış IP adresi sağlamıyor ve bunun yerine NAT aracılığıyla " "İnternet bağlantısı sağlıyor." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -5081,11 +5025,11 @@ msgstr "" "İSS'niz size bir sabit IP adresi sağlamıyor ve IP adresiniz İnternet'e her " "bağlandığınızda değişiyor." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "İSS'niz gelen bağlantıları sınırlıyor." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -5099,23 +5043,23 @@ msgstr "" "href=\"https://pagekite.net\">pagekite.net. Gelecekte bunun için " "arkadaşınızın {box_name} cihazını kullanmak mümkün olabilir." -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Herkese Açık Görünürlük" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite Etki Alanı" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Sunucu etki alanı" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -5123,31 +5067,31 @@ msgstr "" "Pagekite sunucunuzu seçin. Varsayılan pagekite.net sunucusunu kullanmak için " "\"pagekite.net\" olarak ayarlayın." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Sunucu bağlantı noktası" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Pagekite sunucunuzun bağlantı noktası (varsayılan: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite adı" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Örnek: benimkutum.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Geçersiz kite adı" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite gizli anahtarı" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." @@ -5155,35 +5099,35 @@ msgstr "" "Kite ile ilişkilendirilmiş bir gizli anahtar ya da kite üzerinde hiçbir " "gizli anahtar ayarlanmamışsa hesabınız için varsayılan gizli anahtar." -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "protokol" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "harici (ön uç) bağlantı noktası" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "dahili (freedombox) bağlantı noktası" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Alt Etki Alanlarını etkinleştir" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Özel hizmet silindi" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Bu hizmet zaten standart bir hizmet olarak mevcut." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Özel hizmet eklendi" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Bu hizmet zaten var" @@ -5221,32 +5165,32 @@ msgstr "" "dışındaki bağlantı noktalarında HTTPS'nin sorunlara neden olduğu " "bilinmektedir." -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Web Sunucusu (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" "Site http://{0} adresinde kullanılabilir olacaktır" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Web Sunucusu (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" "Site https://{0} adresinde kullanılabilir " "olacaktır" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Güvenli Kabuk (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5298,8 +5242,8 @@ msgstr "" "Şu anda bir kurulum veya yükseltme çalışıyor. Kapatmadan veya yeniden " "başlatmadan önce bitene kadar beklemeyi düşünün." -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Yeniden başlat" @@ -5349,6 +5293,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Şimdi Kapat" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5390,7 +5367,7 @@ msgstr "Web Vekil Sunucusu" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "Tcp{kind} üzerinde {proxy} vekil sunucusu ile {url} adresine erişin" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5407,7 +5384,7 @@ msgstr "" "çalıştırabilir ve bir masaüstünden veya cep telefonundan bir veya daha fazla " "Quassel istemcisini bağlamak ve bağlantısını kesmek için kullanılabilir." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your masaüstü ve mobil cihazlarınızdan bağlanacak istemciler mevcuttur." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC İstemcisi" @@ -5431,7 +5408,7 @@ msgstr "IRC İstemcisi" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5446,7 +5423,7 @@ msgstr "" "\">desteklenen bir istemci uygulaması gereklidir. Radicale'ye {box_name} " "oturum açma adı ile herhangi bir kullanıcı tarafından erişilebilir." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " @@ -5456,12 +5433,12 @@ msgstr "" "temel bir web arayüzü sağlar. Ayrı bir istemci kullanılarak yapılması " "zorunlu olan olayların veya kişilerin eklenmesini desteklemez." -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Takvim ve Adres Defteri" @@ -5536,7 +5513,7 @@ msgstr "" "kullanıcı adınızı girin. Ara düğmesine tıklamak, varolan takvimleri ve adres " "defterlerini listeleyecektir." -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Erişim izinleri yapılandırması güncellendi" @@ -5628,7 +5605,7 @@ msgstr "" "RSS ile RSS-Bridge'i kullanabilirsiniz. Bir bildirim eklerken, kimlik " "doğrulamayı etkinleştirin ve {box_name} kimlik bilgilerinizi kullanın." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Haber bildirimlerini oku ve abone ol" @@ -5641,7 +5618,7 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "RSS Bildirim Oluşturucu" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." @@ -5649,7 +5626,7 @@ msgstr "" "Samba, FreedomBox ile yerel ağınızdaki diğer bilgisayarlar arasında dosya ve " "klasör paylaşmayı sağlar." -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5663,11 +5640,11 @@ msgstr "" "(Linux ve Mac'te) konumunda erişilebilir. Aralarından seçim yapabileceğiniz " "üç tür paylaşım vardır: " -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "Açık paylaşım - yerel ağınızdaki herkes tarafından erişilebilir." -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." @@ -5675,7 +5652,7 @@ msgstr "" "Grup paylaşımı - sadece Freedombox paylaşım grubundaki FreedomBox " "kullanıcıları tarafından erişilebilir." -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." @@ -5683,15 +5660,15 @@ msgstr "" "Ev paylaşımı - Freedombox paylaşım grubundaki her kullanıcı kendi özel " "alanına sahip olabilir." -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Özel paylaşımlara erişim" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Ağ Dosya Depolama" @@ -5778,15 +5755,15 @@ msgstr "Paylaşım adı" msgid "Action" msgstr "Eylem" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox OS disk" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "Açık Paylaşım" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "Grup Paylaşımı" @@ -5812,7 +5789,7 @@ msgstr "Paylaşım etkisizleştirildi." msgid "Error disabling share: {error_message}" msgstr "Paylaşımı etkisizleştirirken hata oldu: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5820,7 +5797,7 @@ msgstr "" "Searx, gizliliğe saygılı bir İnternet üstbilgi arama motorudur. Birden çok " "arama motorundan gelen sonuçları toplar ve görüntüler." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5828,39 +5805,39 @@ msgstr "" "Searx, arama motorları tarafından izlenmeyi ve profil oluşturmayı önlemek " "için kullanılabilir. Varsayılan olarak hiçbir tanımlama bilgisi saklamaz." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Web'de ara" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Web Arama" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Güvenli Arama" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "Arama sonuçlarınıza uygulanacak varsayılan aile süzgecini seçin." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Orta" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Sıkı" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Herkese Açık Erişime izin ver" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Bu uygulamanın, ona ulaşabilen herkes tarafından kullanılmasına izin verin." @@ -6042,7 +6019,7 @@ msgstr "Yer İşaretleri" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " @@ -6052,7 +6029,7 @@ msgstr "" "bir SOCKS5 vekil sunucusudur. İnternet süzmeyi ve sansürü atlamak için " "kullanılabilir." -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -6065,7 +6042,7 @@ msgstr "" "Yerel cihazlar bu vekil sunucuya bağlanabilir ve verileri şifrelenecek ve " "Shadowsocks sunucusu aracılığıyla vekil sunucuya tabi tutulacaktır." -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" @@ -6074,42 +6051,42 @@ msgstr "" "uygulamanızda SOCKS5 vekil sunucu URL'sini http://freedombox_adresi:1080/ " "olarak ayarlayın" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "Shadowsocks" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Socks5 Vekil Sunucusu" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Önerilen" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Sunucu" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Sunucu anamakine adı veya IP adresi" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Sunucu bağlantı noktası numarası" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Verileri şifrelemek için kullanılan parola. Sunucu parolası ile eşleşmek " "zorundadır." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Şifreleme yöntemi. Sunucudaki ayarla eşleşmek zorundadır." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -6118,15 +6095,15 @@ msgstr "" "Paylaşım, web üzerinden {box_name} cihazınızdaki dosyaları ve klasörleri, " "seçilen kullanıcı gruplarıyla paylaşmanızı sağlar." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Paylaşım" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Paylaşım adı" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -6134,27 +6111,27 @@ msgstr "" "Bir paylaşımı benzersiz şekilde tanımlayan küçük harfli alfa-sayısal bir " "dizgi. Örnek: ortam." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Paylaşma yolu" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Bu sunucudaki paylaşmayı düşündüğünüz bir klasörün disk yolu." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Herkese açık paylaşım" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Bu klasördeki dosyaları bağlantıya sahip herkesin kullanımına açın." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Paylaşımdaki dosyaları okuyabilen kullanıcı grupları:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." @@ -6162,11 +6139,11 @@ msgstr "" "Seçilen kullanıcı gruplarının kullanıcıları paylaşımdaki dosyaları " "okuyabilecektir." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Bu ada sahip bir paylaşım zaten var." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Paylaşımlar herkese açık olmalı veya en az bir grupla paylaşılmalıdır" @@ -6203,19 +6180,19 @@ msgstr "Paylaşım eklendi." msgid "Add Share" msgstr "Paylaşım Ekleyin" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Paylaşım düzenlendi." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Paylaşımı Düzenle" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Paylaşım silindi." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -6226,7 +6203,7 @@ msgstr "" "durumunda sistemi önceden bilinen iyi bir duruma geri döndürmek için " "kullanılabilir." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -6238,7 +6215,7 @@ msgstr "" "eski anlık görüntüler, aşağıdaki ayarlara göre otomatik olarak " "temizlenecektir." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for yedeklemelerin " "yerine geçmez. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Depolama Anlık Görüntüleri" @@ -6352,7 +6329,7 @@ msgstr "Tarih" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Anlık Görüntüleri Sil" @@ -6406,58 +6383,58 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "#%(number)s Nolu Anlık Görüntüye Geri Al" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "el ile oluşturuldu" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "zaman çizelgesi" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Anlık Görüntüleri Yönet" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Anlık görüntü oluşturuldu." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Depolama anlık görüntü yapılandırması güncellendi" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Eylem hatası: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Seçilen anlık görüntüler silindi" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Anlık görüntü şu anda kullanımda. Lütfen daha sonra tekrar deneyin." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "#{number} nolu anlık görüntüye geri alındı." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" "Geri alma işlemini tamamlamak için sistem yeniden başlatılmak zorundadır." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "Anlık Görüntüye Geri Al" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6469,7 +6446,7 @@ msgstr "" "bağlantıları kullanarak yönetim görevlerini gerçekleştirebilir, dosyaları " "kopyalayabilir veya diğer hizmetleri çalıştırabilir." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Güvenli Kabuk (SSH) Sunucusu" @@ -6507,14 +6484,6 @@ msgstr "Algoritma" msgid "Fingerprint" msgstr "Parmak İzi" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "Parola ile SSH kimlik doğrulaması etkisizleştirildi." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "Parola ile SSH kimlik doğrulaması etkinleştirildi." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "Tek Oturum Açma" @@ -6527,7 +6496,7 @@ msgstr "Oturum aç" msgid "Logged out successfully." msgstr "Başarılı olarak oturumu kapatıldı." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6539,105 +6508,105 @@ msgstr "" "ortamı bağlayabilir ve bağlantısını kaldırabilir, kök bölümünü vb. " "genişletebilirsiniz." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Depolama" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} bayt" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "İşlem başarısız oldu." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "İşlem iptal edildi." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Aygıtın zaten bağlantısı kaldırılıyor." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "Eksik sürücü/araç desteğinden dolayı işlem desteklenmiyor." -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "İşlem zaman aşımına uğradı." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "İşlem, derin uyku durumunda olan bir diski uyandırır." -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Meşgul olan bir aygıtın bağlantısı kaldırılmaya çalışılıyor." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "İşlem zaten iptal edildi." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "İstenen işlemi gerçekleştirmek için yetkili değilsiniz." -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Aygıt zaten bağlı." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Aygıt bağlı değil." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "İstenen seçeneği kullanmak için izin verilmedi." -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Aygıt başka bir kullanıcı tarafından bağlandı." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Sistem bölümünde düşük alan: %{percent_used} kullanıldı, {free_space} boş." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Düşük disk alanı" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "Disk arızası yakın" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " @@ -6646,39 +6615,39 @@ msgstr "" "Disk {id}, yakın gelecekte başarısız olma ihtimalinin yüksek olduğunu " "bildiriyor. Hala yapabilirken tüm verileri kopyalayın ve sürücüyü değiştirin." -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Geçersiz dizin adı." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Dizin mevcut değil." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Yol bir dizin değil." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Dizin kullanıcı tarafından okunabilir değil." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Dizin kullanıcı tarafından yazılabilir değil." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Dizin" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Alt dizin (isteğe bağlı)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "Paylaş" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Diğer dizin (aşağıda belirtin)" @@ -6715,7 +6684,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Kök Bölümünü Genişlet" @@ -6738,30 +6707,30 @@ msgstr "" "%(expandable_root_size)s ek boş alan kök bölümünüzde kullanılabilir " "olacaktır." -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Bölüm genişletilirken hata oldu: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Bölüm başarılı olarak genişletildi." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} güvenle çıkarılabilir." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Aygıt güvenli bir şekilde çıkarılabilir." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Aygıt çıkarılırken hata oldu: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6773,7 +6742,7 @@ msgstr "" "dosyaların oluşturulması, değiştirilmesi veya silinmesi, Syncthing'i de " "çalıştıran diğer tüm cihazlarda otomatik olarak tekrarlanacaktır." -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6792,20 +6761,20 @@ msgstr "" "{box_name} cihazındaki web arayüzü sadece \"admin\" veya \"syncthing-access" "\" grubuna ait kullanıcılar tarafından kullanılabilir." -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Syncthing uygulamasını yönet" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Dosya Eşitleme" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6818,7 +6787,7 @@ msgstr "" "gezinirken en iyi koruma için Tor Projesi, Tor Tarayıcı kullanmanızı önerir." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6827,40 +6796,40 @@ msgstr "" "9050 nolu TCP bağlantı noktası üzerindeki dahili ağlar için {box_name} " "cihazınızda bir Tor SOCKS bağlantı noktası kullanılabilir." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor Onion Hizmeti" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "Tor Socks Vekil Sunucusu" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor Köprüsü Aktarımı" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor aktarımı bağlantı noktası kullanılabilir" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "Obfs3 taşıma kayıtlı" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "Obfs4 taşıma kayıtlı" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "Tor aracılığıyla tcp{kind} üzerinde erişim URL'si {url}" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "Tcp{kind} üzerinde {url} adresinde Tor kullanımını onaylama" @@ -6980,11 +6949,11 @@ msgstr "Onion Hizmeti" msgid "Ports" msgstr "Bağlantı Noktaları" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Yapılandırma güncelleniyor" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Uygulama yapılandırılırken hata oldu: {error}" @@ -7048,7 +7017,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -7058,7 +7027,7 @@ msgstr "" "hissettiren herhangi bir konumdan haberleri okumayı sağlamak için " "tasarlanmış bir haber bildirim (RSS/Atom) okuyucusu ve toplayıcısıdır." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -7067,7 +7036,7 @@ msgstr "" "Etkinleştirildiğinde Tiny Tiny RSS'ye, bildirim okuyucu grubuna ait herhangi bir kullanıcı tarafından erişilebilir." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -7075,11 +7044,11 @@ msgstr "" "Tiny Tiny RSS için bir mobil veya masaüstü uygulaması kullanırken, bağlanmak " "için /tt-rss-app URL'sini kullanın." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Haber Bildirim Okuyucusu" @@ -7087,12 +7056,12 @@ msgstr "Haber Bildirim Okuyucusu" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (Fork)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "En son yazılım ve güvenlik güncellemelerini denetleyin ve uygulayın." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -7105,22 +7074,22 @@ msgstr "" "Eğer sistemin yeniden başlatılması gerekli görülürse, saat 02:00'da otomatik " "olarak yapılır ve tüm uygulamalar kısa bir süre için kullanılamaz hale gelir." -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Yazılım Güncellemesi" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox Güncellendi" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Dağıtım güncellemesi başlatılamadı" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " @@ -7130,11 +7099,11 @@ msgstr "" "Lütfen en az 5 GB boş alan olduğundan emin olun. Dağıtım güncellemesi, " "etkinleştirildiyse 24 saat sonra yeniden denenecektir." -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Dağıtım güncellemesi başlatıldı" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -7313,44 +7282,44 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Dağıtım yükseltmesini şimdi dene" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "unattended-upgrades yapılandırılırken bir hata oldu: {error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Otomatik yükseltmeler etkinleştirildi" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Otomatik yükseltmeler etkisizleştirildi" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Dağıtım yükseltmesi etkinleştirildi" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Dağıtım yükseltmesi etkisizleştirildi" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Yükseltme işlemi başladı." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Yükseltmeyi başlatma başarısız oldu." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Sık yapılan özellik güncellemeleri etkinleştirildi." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Dağıtım yükseltmesi denemesi başlatılıyor." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -7361,7 +7330,7 @@ msgstr "" "kullanıcıya, uygulamaya erişme yetkisi vermek için bir kullanıcı hesabının " "bir grubun parçası olmasını gerektirir." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -7373,15 +7342,15 @@ msgstr "" "sadece admin grubunun kullanıcıları uygulamaları veya sistem " "ayarlarını değiştirebilir." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Kullanıcılar ve Gruplar" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Tüm hizmetlere ve sistem ayarlarına erişim" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "LDAP \"{search_item}\" girişini denetleme" @@ -7401,11 +7370,11 @@ msgstr "" "Zorunlu. 150 veya daha az karakter. Sadece İngilizce harfler, rakamlar ve " "@/./-/_ karakterleri." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Yetkilendirme Parolası" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7413,11 +7382,11 @@ msgstr "" "Hesap değişikliklerini yetkilendirmek için \"{user}\" kullanıcısının " "parolasını girin." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Geçersiz parola." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7431,12 +7400,12 @@ msgstr "" "kullanıcılar tüm hizmetlere oturum açabilecektir. Ayrıca SSH aracılığıyla " "sisteme oturum açabilir ve yönetici yetkilerine (sudo) sahip olabilirler." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "LDAP kullanıcısı oluşturma başarısız oldu: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "{group} grubuna yeni kullanıcı ekleme başarısız oldu: {error}" @@ -7456,41 +7425,41 @@ msgstr "" "tane olmak üzere birden çok anahtar girebilirsiniz. Boş satırlar ve # ile " "başlayan satırlar yoksayılacaktır." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "LDAP kullanıcısının yeniden adlandırılması başarısız oldu." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Kullanıcıyı gruptan kaldırma başarısız oldu." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Kullanıcıyı gruba ekleme başarısız oldu." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "SSH anahtarları ayarlanamıyor." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Kullanıcı durumunu değiştirme başarısız oldu." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "LDAP kullanıcı parolasının değiştirilmesi başarısız oldu." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Admin grubuna yeni kullanıcı ekleme başarısız oldu: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Konsol erişimini kısıtlama başarısız oldu: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Kullanıcı hesabı oluşturuldu, şu an oturum açtınız" @@ -7507,12 +7476,12 @@ msgstr "Parolayı Kaydet" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Kullanıcı Oluştur" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Kullanıcıyı Sil" @@ -7553,13 +7522,19 @@ msgid "The following administrator accounts exist in the system." msgstr "Sistemde aşağıdaki yönetici hesapları var." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, fuzzy, python-format +#| msgid "" +#| "Delete these accounts from command line and refresh the page to create an " +#| "account that is usable with %(box_name)s. On the command line run the " +#| "command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-" +#| "user {username}'. If an account is already usable with %(box_name)s, skip " +#| "this step." msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" "Bu hesapları komut satırından silin ve %(box_name)s ile kullanılabilen bir " "hesap oluşturmak için sayfayı yenileyin. Komut satırında 'echo " @@ -7568,7 +7543,7 @@ msgstr "" "bu adımı atlayın." #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Kullanıcılar" @@ -7601,34 +7576,34 @@ msgstr "" msgid "Save Changes" msgstr "Değişiklikleri Kaydet" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "%(username)s kullanıcısı oluşturuldu." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "%(username)s kullanıcısı güncellendi." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Kullanıcıyı Düzenle" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "{user} kullanıcısı silindi." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "LDAP kullanıcısının silinmesi başarısız oldu." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Parolayı Değiştir" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Parola başarılı olarak değiştirildi." @@ -7963,7 +7938,7 @@ msgstr "Sunucuya Bağlantıyı Sil" msgid "Server deleted." msgstr "Sunucu silindi." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7977,7 +7952,7 @@ msgstr "" "kullanılarak seçilebilir. Yönetim arayüzü ve üretilen web sayfaları mobil " "cihazlara uygundur." -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7991,7 +7966,7 @@ msgstr "" "Sayfalarınıza ve yazılarınıza daha iyi URL'ler sağlamak için yönetici " "arayüzünde kalıcı bağlantıları etkinleştirin." -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " @@ -8001,7 +7976,7 @@ msgstr "" "sırasında oluşturulur. Gelecekte yönetim arayüzüne erişmek için yönetici sayfası yerini işaretleyin." -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " @@ -8011,12 +7986,12 @@ msgstr "" "yükseltmesini el ile çalıştırmanız gerekir. Ek eklentiler veya temalar kendi " "sorumluluğunuzda yüklenebilir ve yükseltilebilir." -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Web Sitesi ve Blog" @@ -8033,7 +8008,7 @@ msgstr "" "WordPress sitesini veya blogunu görüntülemesine izin verir. Sadece ilk " "WordPress kurulumunu gerçekleştirdikten sonra etkinleştirin." -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -8055,7 +8030,7 @@ msgstr "" "çekilmiş fotoğrafları bulmak kolaydır. Tek tek fotoğraflar, doğrudan bir " "bağlantı gönderilerek başkalarıyla paylaşılabilir." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -8066,11 +8041,11 @@ msgstr "" "Ek kullanıcılar için hesaplar hem {box_name} cihazında hem de Zoph'da aynı " "kullanıcı adıyla oluşturulmak zorundadır." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Fotoğraf Düzenleyici" @@ -8123,96 +8098,92 @@ msgstr "Başlamak için bekleniyor: {name}" msgid "Finished: {name}" msgstr "Tamamlandı: {name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "{expression} paketi yükleme için mevcut değil" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "{package_name} paketi en son sürümdür ({latest_version})" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "apt-get çalıştırılırken hata oldu" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "yükleniyor" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "indiriliyor" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "ortam değiştirme" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "yapılandırma dosyası: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "Paket yöneticisini beklerken zaman aşımı oldu" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Uygulama yükleniyor" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Uygulama güncelleniyor" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Uygulama yüklenirken hata oldu: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Uygulama güncellenirken hata oldu: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Uygulama yüklenirken hata oldu: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Uygulama güncellenirken hata oldu: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "Uygulama yüklendi." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "Uygulama güncellendi" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Uygulama kaldırılıyor" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Uygulama kaldırılırken hata oldu: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Uygulama kaldırılırken hata oldu: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "Uygulama kaldırıldı." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Uygulama paketleri güncelleniyor" @@ -8272,53 +8243,54 @@ msgstr "Kurulum" msgid "Service %(service_name)s is not running." msgstr "%(service_name)s hizmeti çalışmıyor." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "%(box_name)s için temel işlevsellik ve web arayüzü" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Giriş" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Giriş" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Uygulamalar" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Uygulamalar" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Sistem" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Sistem" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Parolayı değiştir" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Kapat" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Oturumu kapat" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Dil seçin" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Oturum aç" @@ -8606,6 +8578,75 @@ msgstr "{app_id} kaldırılmadan önce" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "DNSSEC'i etkinleştir" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Etki Alanı Adı Sistemi Güvenlik Uzantılarını etkinleştir" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Güvenlik duvarı arka plan programı çalışmıyor. Lütfen çalıştırın. " +#~ "Güvenlik duvarı varsayılan olarak %(box_name)s ile etkinleştirilmiş " +#~ "gelir. Herhangi bir Debian tabanlı sistemde (%(box_name)s gibi), 'service " +#~ "firewalld start' komutunu kullanarak veya systemd 'systemctl start " +#~ "firewalld' olan bir sistem durumunda çalıştırabilirsiniz." + +#~ msgid "Migrate to ECC" +#~ msgstr "ECC'ye Geçir" + +#~ msgid "" +#~ "Your OpenVPN installation is currently using RSA. Switching to the modern " +#~ "Elliptic Curve Cryptography improves speed of establishing a connection " +#~ "and security. This operation is irreversible. It should only take a few " +#~ "minutes on most single board computers." +#~ msgstr "" +#~ "OpenVPN kurulumunuz şu anda RSA kullanıyor. Modern Eliptik Eğri " +#~ "Şifrelemesine geçiş, bağlantı kurma hızını ve güvenliği artırır. Bu işlem " +#~ "geri alınamaz. Çoğu tek kartlı bilgisayarda sadece birkaç dakika " +#~ "sürmektedir." + +#, python-format +#~ msgid "" +#~ "All new installations of OpenVPN on %(box_name)s will use ECC by default. " +#~ "We recommend migrating as soon as possible." +#~ msgstr "" +#~ "%(box_name)s cihazındaki tüm yeni OpenVPN kurulumları, varsayılan olarak " +#~ "ECC'yi kullanacaktır. Mümkün olan en kısa sürede geçiş yapmanızı öneririz." + +#, python-format +#~ msgid "" +#~ "Warning: Existing client profiles will be invalidated by this " +#~ "operation. All OpenVPN users on %(box_name)s must download their new " +#~ "profiles. OpenVPN clients compatible with ECC should be used to connect " +#~ "to this server." +#~ msgstr "" +#~ "Uyarı: Varolan istemci profilleri bu işlem tarafından geçersiz " +#~ "kılınacaktır. %(box_name)s cihazındaki tüm OpenVPN kullanıcıları yeni " +#~ "profillerini indirmek zorundadır. Bu sunucuya bağlanmak için ECC ile " +#~ "uyumlu OpenVPN istemcileri kullanılmalıdır." + +#~ msgid "Migrate" +#~ msgstr "Geçir" + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "Parola ile SSH kimlik doğrulaması etkisizleştirildi." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "Parola ile SSH kimlik doğrulaması etkinleştirildi." + +#~ msgid "Error running apt-get" +#~ msgstr "apt-get çalıştırılırken hata oldu" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "%(box_name)s için temel işlevsellik ve web arayüzü" + #~ msgid "Network Connections" #~ msgstr "Ağ Bağlantıları" diff --git a/plinth/locale/uk/LC_MESSAGES/django.po b/plinth/locale/uk/LC_MESSAGES/django.po index b2a809053..a3bb66483 100644 --- a/plinth/locale/uk/LC_MESSAGES/django.po +++ b/plinth/locale/uk/LC_MESSAGES/django.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" -"PO-Revision-Date: 2022-10-01 13:58+0000\n" -"Last-Translator: Andrij Mizyk \n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" +"PO-Revision-Date: 2022-10-09 07:43+0000\n" +"Last-Translator: Tymofii Lytvynenko \n" "Language-Team: Ukrainian \n" "Language: uk\n" @@ -116,17 +116,17 @@ msgstr "Вебсервер" msgid "{box_name} Web Interface (Plinth)" msgstr "Вебінтерфейс {box_name} (Plinth)" -#: plinth/modules/apache/components.py:126 +#: plinth/modules/apache/components.py:121 #, python-brace-format msgid "Access URL {url} on tcp{kind}" msgstr "Доступ до URL {url} по tcp {kind}" -#: plinth/modules/apache/components.py:129 +#: plinth/modules/apache/components.py:124 #, python-brace-format msgid "Access URL {url}" msgstr "Доступ до URL {url}" -#: plinth/modules/avahi/__init__.py:26 +#: plinth/modules/avahi/__init__.py:24 #, python-brace-format msgid "" "Service discovery allows other devices on the network to discover your " @@ -142,25 +142,25 @@ msgstr "" "сервісів не головне і працює лише у внутрішніх мережах. Це можна вимкнути " "для підвищення безпеки, особливо при підключенні до недовіреної мережі." -#: plinth/modules/avahi/__init__.py:49 +#: plinth/modules/avahi/__init__.py:47 msgid "Service Discovery" msgstr "Виявлення служб" -#: plinth/modules/avahi/__init__.py:62 +#: plinth/modules/avahi/__init__.py:60 msgid "Local Network Domain" msgstr "Домен локальної мережі" -#: plinth/modules/backups/__init__.py:27 +#: plinth/modules/backups/__init__.py:24 msgid "Backups allows creating and managing backup archives." msgstr "" "Резервне копіювання дозволяє створювати та керувати резервними архівами." -#: plinth/modules/backups/__init__.py:48 plinth/modules/backups/__init__.py:199 -#: plinth/modules/backups/__init__.py:244 +#: plinth/modules/backups/__init__.py:44 plinth/modules/backups/__init__.py:169 +#: plinth/modules/backups/__init__.py:214 msgid "Backups" msgstr "Резервні копії" -#: plinth/modules/backups/__init__.py:196 +#: plinth/modules/backups/__init__.py:166 msgid "" "Enable an automatic backup schedule for data safety. Prefer an encrypted " "remote backup location or an extra attached disk." @@ -169,18 +169,18 @@ msgstr "" "Для резервних копій надається перевага віддаленому зашифрованому " "розташуванню або зовнішньому знімному диску." -#: plinth/modules/backups/__init__.py:202 +#: plinth/modules/backups/__init__.py:172 msgid "Enable a Backup Schedule" msgstr "Дозволити планування резервних копій" -#: plinth/modules/backups/__init__.py:206 -#: plinth/modules/backups/__init__.py:253 -#: plinth/modules/storage/__init__.py:326 +#: plinth/modules/backups/__init__.py:176 +#: plinth/modules/backups/__init__.py:223 plinth/modules/privacy/__init__.py:71 +#: plinth/modules/storage/__init__.py:313 #, python-brace-format msgid "Go to {app_name}" msgstr "Перейти в {app_name}" -#: plinth/modules/backups/__init__.py:241 +#: plinth/modules/backups/__init__.py:211 #, python-brace-format msgid "" "A scheduled backup failed. Past {error_count} attempts for backup did not " @@ -189,7 +189,7 @@ msgstr "" "Невдале заплановане резервне копіювання. Минулі {error_count} спроб не були " "успішними. Остання помилка: {error_message}" -#: plinth/modules/backups/__init__.py:249 +#: plinth/modules/backups/__init__.py:219 msgid "Error During Backup" msgstr "Помилка під час резервного копіювання" @@ -334,7 +334,7 @@ msgstr "" msgid "Key in Repository" msgstr "Ключ у репозиторії" -#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:15 +#: plinth/modules/backups/forms.py:176 plinth/modules/searx/forms.py:14 msgid "None" msgstr "Нічого" @@ -402,7 +402,7 @@ msgstr "Віддалений репозиторій резервних копі msgid "Select verified SSH public key" msgstr "Вибрати перевірений публічний ключ SSH" -#: plinth/modules/backups/repository.py:34 +#: plinth/modules/backups/repository.py:30 msgid "" "Connection refused - make sure you provided correct credentials and the " "server is running." @@ -410,32 +410,32 @@ msgstr "" "У зʼєднані відмовлено – переконайтеся, що надано правильні облікові дані і " "чи сервер працює." -#: plinth/modules/backups/repository.py:41 +#: plinth/modules/backups/repository.py:37 msgid "Connection refused" msgstr "З’єднання відхилено" -#: plinth/modules/backups/repository.py:48 +#: plinth/modules/backups/repository.py:44 msgid "Repository not found" msgstr "Репозиторій не знайдено" -#: plinth/modules/backups/repository.py:53 +#: plinth/modules/backups/repository.py:49 msgid "Incorrect encryption passphrase" msgstr "Неправильна парольна фраза для шифрування" -#: plinth/modules/backups/repository.py:58 +#: plinth/modules/backups/repository.py:54 msgid "SSH access denied" msgstr "Доступ SSH відхилено" -#: plinth/modules/backups/repository.py:64 +#: plinth/modules/backups/repository.py:60 msgid "Repository path is neither empty nor is an existing backups repository." msgstr "" "Шлях репозиторію непорожній і не є наявним репозиторієм резервних копій." -#: plinth/modules/backups/repository.py:147 +#: plinth/modules/backups/repository.py:145 msgid "Existing repository is not encrypted." msgstr "Наявний репозиторій не зашифровано." -#: plinth/modules/backups/repository.py:331 +#: plinth/modules/backups/repository.py:335 #, python-brace-format msgid "{box_name} storage" msgstr "Сховище {box_name}" @@ -493,7 +493,7 @@ msgid "Create Location" msgstr "Створити розташування" #: plinth/modules/backups/templates/backups_add_repository.html:19 -#: plinth/modules/gitweb/views.py:54 +#: plinth/modules/gitweb/views.py:51 msgid "Create Repository" msgstr "Створити репозиторій" @@ -736,7 +736,7 @@ msgstr "Не вдалося відмонтувати!" msgid "Mounting failed" msgstr "Не вдалося змонтувати" -#: plinth/modules/bepasty/__init__.py:21 +#: plinth/modules/bepasty/__init__.py:16 msgid "" "bepasty is a web application that allows large files to be uploaded and " "shared. Text and code snippets can also be pasted and shared. Text, image, " @@ -749,7 +749,7 @@ msgstr "" "оглядачі. Поширювані файли можна позначати застарілими після певного періоду " "часу." -#: plinth/modules/bepasty/__init__.py:25 +#: plinth/modules/bepasty/__init__.py:20 msgid "" "bepasty does not use usernames for login. It only uses passwords. For each " "password, a set of permissions can be selected. Once you have created a " @@ -760,7 +760,7 @@ msgstr "" "паролі. Для кожного пароля можна вибрати набір дозволів. Створивши пароль, " "Ви зможете поділитися ним із користувачами, які мають відповідні дозволи." -#: plinth/modules/bepasty/__init__.py:29 +#: plinth/modules/bepasty/__init__.py:24 msgid "" "You can also create multiple passwords with the same set of privileges, and " "distribute them to different people or groups. This will allow you to later " @@ -771,39 +771,39 @@ msgstr "" "різним людям або групам. Це дозволить скасувати доступ до певної особи або " "групи видаливши її пароль зі списку." -#: plinth/modules/bepasty/__init__.py:36 plinth/modules/bepasty/__init__.py:45 +#: plinth/modules/bepasty/__init__.py:31 plinth/modules/bepasty/__init__.py:40 msgid "Read a file, if a web link to the file is available" msgstr "Прочитати файл, якщо вебпосилання на файл доступне" -#: plinth/modules/bepasty/__init__.py:37 +#: plinth/modules/bepasty/__init__.py:32 msgid "Create or upload files" msgstr "Створити або відвантажити файли" -#: plinth/modules/bepasty/__init__.py:38 +#: plinth/modules/bepasty/__init__.py:33 msgid "List all files and their web links" msgstr "Показати всі файли і їхні вебпосилання" -#: plinth/modules/bepasty/__init__.py:39 +#: plinth/modules/bepasty/__init__.py:34 msgid "Delete files" msgstr "Видалити файли" -#: plinth/modules/bepasty/__init__.py:40 +#: plinth/modules/bepasty/__init__.py:35 msgid "Administer files: lock/unlock files" msgstr "Адміністрування файлів: блокувати/розблокувати файли" -#: plinth/modules/bepasty/__init__.py:44 +#: plinth/modules/bepasty/__init__.py:39 msgid "None, password is always required" msgstr "Нічого, пароль обовʼязковий" -#: plinth/modules/bepasty/__init__.py:46 +#: plinth/modules/bepasty/__init__.py:41 msgid "List and read all files" msgstr "Показати і зчитати всі файли" -#: plinth/modules/bepasty/__init__.py:61 plinth/modules/bepasty/manifest.py:6 +#: plinth/modules/bepasty/__init__.py:56 plinth/modules/bepasty/manifest.py:6 msgid "bepasty" msgstr "bepasty" -#: plinth/modules/bepasty/__init__.py:63 +#: plinth/modules/bepasty/__init__.py:58 msgid "File & Snippet Sharing" msgstr "Обмін файлами і фрагментами коду" @@ -817,7 +817,7 @@ msgstr "Дозволи для анонімних користувачів, що #: plinth/modules/bepasty/forms.py:27 #: plinth/modules/bepasty/templates/bepasty.html:30 -#: plinth/modules/users/forms.py:108 plinth/modules/users/forms.py:234 +#: plinth/modules/users/forms.py:111 plinth/modules/users/forms.py:235 msgid "Permissions" msgstr "Дозволи" @@ -850,35 +850,35 @@ msgstr "Не налаштовано жодного пароля." #: plinth/modules/bepasty/templates/bepasty.html:29 #: plinth/modules/dynamicdns/forms.py:91 plinth/modules/networks/forms.py:213 -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password" msgstr "Пароль" -#: plinth/modules/bepasty/views.py:22 +#: plinth/modules/bepasty/views.py:19 msgid "admin" msgstr "адміністратор" -#: plinth/modules/bepasty/views.py:23 +#: plinth/modules/bepasty/views.py:20 msgid "editor" msgstr "редактор" -#: plinth/modules/bepasty/views.py:24 +#: plinth/modules/bepasty/views.py:21 msgid "viewer" msgstr "переглядач" -#: plinth/modules/bepasty/views.py:49 +#: plinth/modules/bepasty/views.py:47 msgid "Read" msgstr "Читати" -#: plinth/modules/bepasty/views.py:50 +#: plinth/modules/bepasty/views.py:48 msgid "Create" msgstr "Створити" -#: plinth/modules/bepasty/views.py:51 +#: plinth/modules/bepasty/views.py:49 msgid "List" msgstr "Показати" -#: plinth/modules/bepasty/views.py:52 +#: plinth/modules/bepasty/views.py:50 #: plinth/modules/email/templates/email-aliases.html:24 #: plinth/modules/letsencrypt/templates/letsencrypt.html:86 #: plinth/modules/networks/templates/connection_show.html:56 @@ -890,35 +890,35 @@ msgstr "Показати" msgid "Delete" msgstr "Видалити" -#: plinth/modules/bepasty/views.py:53 +#: plinth/modules/bepasty/views.py:51 msgid "Admin" msgstr "Адміністратор" -#: plinth/modules/bepasty/views.py:90 plinth/modules/searx/views.py:40 -#: plinth/modules/searx/views.py:51 plinth/modules/tor/views.py:75 +#: plinth/modules/bepasty/views.py:88 plinth/modules/searx/views.py:35 +#: plinth/modules/searx/views.py:46 plinth/modules/tor/views.py:73 #: plinth/modules/zoph/views.py:71 msgid "Configuration updated." msgstr "Налаштування оновлено." -#: plinth/modules/bepasty/views.py:93 plinth/modules/email/views.py:48 -#: plinth/modules/gitweb/views.py:121 plinth/modules/searx/views.py:43 -#: plinth/modules/searx/views.py:54 plinth/modules/zoph/views.py:74 +#: plinth/modules/bepasty/views.py:91 plinth/modules/email/views.py:48 +#: plinth/modules/gitweb/views.py:117 plinth/modules/searx/views.py:38 +#: plinth/modules/searx/views.py:49 plinth/modules/zoph/views.py:74 msgid "An error occurred during configuration." msgstr "Під час налаштування відбулася помилка." -#: plinth/modules/bepasty/views.py:105 +#: plinth/modules/bepasty/views.py:103 msgid "Password added." msgstr "Пароль додано." -#: plinth/modules/bepasty/views.py:110 +#: plinth/modules/bepasty/views.py:108 msgid "Add Password" msgstr "Додати пароль" -#: plinth/modules/bepasty/views.py:127 +#: plinth/modules/bepasty/views.py:122 msgid "Password deleted." msgstr "Пароль видалено." -#: plinth/modules/bind/__init__.py:25 +#: plinth/modules/bind/__init__.py:17 msgid "" "BIND enables you to publish your Domain Name System (DNS) information on the " "Internet, and to resolve DNS queries for your user devices on your network." @@ -926,7 +926,7 @@ msgstr "" "BIND дозволяє публікувати інформацію про доменні назви (DNS) і надає дозволи " "на DNS-запити пристроїв у Вашій мережі." -#: plinth/modules/bind/__init__.py:29 +#: plinth/modules/bind/__init__.py:21 #, python-brace-format msgid "" "Currently, on {box_name}, BIND is only used to resolve DNS queries for other " @@ -937,32 +937,24 @@ msgstr "" "інших машин у локальній мережі. Це також не сумісно зі спільним доступом до " "Інтернету з {box_name}." -#: plinth/modules/bind/__init__.py:74 +#: plinth/modules/bind/__init__.py:40 msgid "BIND" msgstr "BIND" -#: plinth/modules/bind/__init__.py:75 +#: plinth/modules/bind/__init__.py:41 msgid "Domain Name Server" msgstr "Сервер доменних імен" -#: plinth/modules/bind/forms.py:20 +#: plinth/modules/bind/forms.py:19 msgid "Forwarders" msgstr "Перенаправлювачі" -#: plinth/modules/bind/forms.py:21 +#: plinth/modules/bind/forms.py:20 msgid "" "A list DNS servers, separated by space, to which requests will be forwarded" msgstr "" "Список серверів DNS, що розділені пробілами, до яких направлятимуться запити" -#: plinth/modules/bind/forms.py:25 -msgid "Enable DNSSEC" -msgstr "Увімкнути DNSSEC" - -#: plinth/modules/bind/forms.py:26 -msgid "Enable Domain Name System Security Extensions" -msgstr "Дозволити розширення безпеки системи доменних назв" - #: plinth/modules/bind/templates/bind.html:11 msgid "Serving Domains" msgstr "Обслуговування доменів" @@ -994,19 +986,20 @@ msgstr "IP-адреси" msgid "Refresh IP address and domains" msgstr "Оновити IP-адреси і домени" -#: plinth/modules/bind/views.py:71 plinth/modules/config/views.py:99 -#: plinth/modules/coturn/views.py:41 plinth/modules/deluge/views.py:42 -#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:96 -#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:126 -#: plinth/modules/minetest/views.py:69 plinth/modules/mumble/views.py:37 -#: plinth/modules/pagekite/forms.py:78 plinth/modules/quassel/views.py:29 -#: plinth/modules/roundcube/views.py:32 plinth/modules/shadowsocks/views.py:59 -#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:26 -#: plinth/modules/wordpress/views.py:37 +#: plinth/modules/bind/views.py:61 plinth/modules/config/views.py:98 +#: plinth/modules/coturn/views.py:40 plinth/modules/deluge/views.py:35 +#: plinth/modules/dynamicdns/views.py:78 plinth/modules/ejabberd/views.py:95 +#: plinth/modules/email/views.py:45 plinth/modules/matrixsynapse/views.py:128 +#: plinth/modules/minetest/views.py:55 plinth/modules/mumble/views.py:37 +#: plinth/modules/pagekite/forms.py:74 plinth/modules/privacy/views.py:36 +#: plinth/modules/quassel/views.py:29 plinth/modules/roundcube/views.py:32 +#: plinth/modules/shadowsocks/views.py:53 plinth/modules/ssh/views.py:52 +#: plinth/modules/transmission/views.py:43 plinth/modules/ttrss/views.py:31 +#: plinth/modules/wordpress/views.py:31 msgid "Configuration updated" msgstr "Конфігурацію оновлено" -#: plinth/modules/calibre/__init__.py:26 +#: plinth/modules/calibre/__init__.py:22 #, python-brace-format msgid "" "calibre server provides online access to your e-book collection. You can " @@ -1017,7 +1010,7 @@ msgstr "" "Можете зберігати електронні книжки на своєму {box_name}, читаючи їх у мережі " "або з будь-якого Вашого пристрою." -#: plinth/modules/calibre/__init__.py:29 +#: plinth/modules/calibre/__init__.py:25 msgid "" "You can organize your e-books, extract and edit their metadata, and perform " "advanced search. calibre can import, export, or convert across a wide range " @@ -1033,7 +1026,7 @@ msgstr "" "закладки і виділений текст. Поширення вмісту через OPDS поки що не " "підтримується." -#: plinth/modules/calibre/__init__.py:35 +#: plinth/modules/calibre/__init__.py:31 msgid "" "Only users belonging to calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1042,23 +1035,23 @@ msgstr "" "до застосунку. Усі користувачі з доступом можуть користуватися всіма " "бібліотеками." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Використання бібліотеки ел. книжок calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Бібліотека ел. книжок" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Назва нової бібліотеки" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" @@ -1066,7 +1059,7 @@ msgstr "" "Лише букви англійського алфавіту, цифри та знаки _ і - без пробілів чи " "спеціальних символів. Наприклад: My_Library_2000" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Бібліотека з такою назвою вже існує." @@ -1114,20 +1107,20 @@ msgstr "Перейти до бібліотеки %(library)s" msgid "Delete library %(library)s" msgstr "Видалити бібліотеку %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Бібліотеку створено." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Помилка виникла під час створення бібліотеки." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} видалено." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Не вдалося видалити {name}: {error}" @@ -1175,7 +1168,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Адміністрування сервера" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1183,18 +1176,18 @@ msgstr "" "Тут Ви можете задати деякі загальні параметри налаштувань, як-от назва " "компʼютера, назва домена, домашня сторінка вебсервера тощо." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Загальні налаштування" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Налаштування" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1310,47 +1303,47 @@ msgstr "" "Журнали містять інформацію про те, хто мав доступ до системи та інформацію " "про зневадження від різних сервісів" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Помилка параметру hostname: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Назву компʼютера задано" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Помилка встановлення доменної назви: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Доменну назву задано" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Помилка налаштування домашньої сторінки вебсервера: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Домашню сторінку вебсервера задано" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Помилка зміни розширеного режиму: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Відображення розширених застосунків і можливостей" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Приховування розширених застосунків і можливостей" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1362,7 +1355,7 @@ msgstr "" "комунікації можуть використовувати його для встановлення дзвінків між " "частинами, які по-іншому не можливо звʼязати між собою." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse або ejabberd потрібно налаштовувати з урахуванням деталей наведених тут." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Помічник VoIP" @@ -1436,11 +1429,11 @@ msgstr "Помилка задавання часового поясу: {exceptio msgid "Time zone set" msgstr "Часовий пояс задано" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge – це клієнт BitTorrent із вебінтерфейсом." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1448,16 +1441,16 @@ msgstr "" "Типовий пароль – 'deluge', але Ви можете ввійти і змінити його відразу після " "ввімкнення цього сервісу." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Завантаження файлів через застосунки BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Вебклієнт BitTorrent" @@ -1584,7 +1577,7 @@ msgstr "Результат" msgid "Diagnostic Test" msgstr "Тест діагностики" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1595,7 +1588,7 @@ msgstr "" "кожних 24год.), то іншим може бути важко знайти Вас в Інтернеті. Це " "перешкоджатиме іншим пошук сервісів, що надаються цим {box_name}." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1605,20 +1598,32 @@ msgid "" "Internet asks for your DNS name, they will get a response with your current " "IP address." msgstr "" +"Рішення полягає в тому, щоб призначити DNS-ім'я вашій IP-адресі та " +"оновлювати DNS-ім'я кожного разу, коли ваша IP-адреса змінюється вашим " +"Інтернет-провайдером. Динамічна DNS дозволяє вам передати вашу поточну " +"публічну IP-адресу на сервер GnuDIP. Після цього сервер призначить ваше DNS-ім'я " +"новому IP, і якщо хтось з Інтернету запитає ваше DNS-ім'я, він отримає " +"відповідь з вашою поточною IP-адресою." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." "freedombox.org or you may find free update URL based services at freedns.afraid.org." msgstr "" +"Якщо ви шукаєте безплатний динамічний обліковий запис DNS, ви можете знайти " +"безплатну службу GnuDIP за адресою ddns.freedombox.org або ви можете знайти безплатні " +"служби на основі URL-адреси оновлення за адресою freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Клієнт динамічної DNS" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Динамічна доменна назва" @@ -1628,6 +1633,9 @@ msgid "" "used within the URL. For details see the update URL templates of the example " "providers." msgstr "" +"Змінні <User>, <Pass>, <Ip>, <Domain> можуть " +"використовуватися в URL-адресі. Докладніше див. шаблони оновлених URL-адрес " +"прикладів провайдерів." #: plinth/modules/dynamicdns/forms.py:22 msgid "" @@ -1635,6 +1643,9 @@ msgid "" "provider does not support the GnuDIP protocol or your provider is not listed " "you may use the update URL of your provider." msgstr "" +"Оберіть протокол оновлення відповідно до вашого провайдера. Якщо ваш " +"провайдер не підтримує протокол GnuDIP або ваш провайдер відсутній у списку, " +"ви можете використовувати URL-адресу оновлення вашого провайдера." #: plinth/modules/dynamicdns/forms.py:27 msgid "" @@ -1676,6 +1687,11 @@ msgid "" "address. The URL should simply return the IP where the client comes from " "(example: https://ddns.freedombox.org/ip/)." msgstr "" +"Необов'язкове значення. Якщо ваш {box_name} не підключений безпосередньо до " +"Інтернету (тобто підключений до NAT-маршрутизатора), ця URL-адреса " +"використовується для визначення реальної IP-адреси. URL-адреса повинна " +"просто повертати IP-адресу, з якої приходить клієнт (наприклад: https://ddns." +"freedombox.org/ip/)." #: plinth/modules/dynamicdns/forms.py:51 msgid "The username that was used when the account was created." @@ -1739,7 +1755,7 @@ msgstr "Це поле обовʼязкове." #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1794,7 +1810,7 @@ msgstr "Сервер відмовив у зʼєднанні" msgid "Already up-to-date" msgstr "Вже оновлено" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1802,7 +1818,7 @@ msgstr "" "XMPP – це відкритий і стандартизований протокол спілкування. Тут Ви можете " "запустити і налаштувати свій XMPP-сервер ejabberd." -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web clientклієнт XMPP. Якщо ввімкнено, то отримати доступ до ejabberd " "зможе будь-який користувач із логіном {box_name}." -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn або налаштуйте зовнішній " "сервер." -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "Сервер чату" @@ -1843,6 +1859,9 @@ msgid "" "Domains to be used by ejabberd. Note that user accounts are unique for each " "domain, and migrating users to a new domain name is not yet implemented." msgstr "" +"Домени, які будуть використовуватися ejabberd. Зверніть увагу, що облікові " +"записи користувачів є неповторюваними для кожного домену, і міграція " +"користувачів на нове доменне ім'я поки що не реалізована." #: plinth/modules/ejabberd/forms.py:26 msgid "Enable Message Archive Management" @@ -1949,22 +1968,31 @@ msgstr "" "виглядатиме як username@%(domainname)s. Ви можете налаштувати свій " "домен на системній сторінці Налаштувати." -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" +"Це комплексне рішення для поштового сервера з використанням Postfix, Dovecot " +"та Rspamd. Postfix відправляє та отримує електронні листи. Dovecot дозволяє " +"поштовим клієнтам отримувати доступ до вашої поштової скриньки за допомогою " +"IMAP і POP3. Rspamd блокує спам." -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " "restrict outgoing email. Some lift the restriction after an explicit " "request. See manual page for more information." msgstr "" +"Поштовий сервер наразі не працює з багатьма безплатними доменними службами, " +"в тому числі з тими, що надаються Фундацією FreedomBox. Багато Інтернет-" +"провайдерів також обмежують вихідну електронну пошту. Деякі з них знімають " +"обмеження після явного запиту. Дивіться сторінку посібника для отримання " +"подробиць." -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1973,8 +2001,14 @@ msgid "" "Necessary aliases such as \"postmaster\" are automatically created pointing " "to the first admin user." msgstr "" +"Кожен користувач на {box_name} отримує адресу електронної пошти на зразок " +"user@mydomain.example. Вони також отримуватимуть пошту з усіх адрес, які " +"мають вигляд user+foo@mydomain.example. Крім того, вони можуть додавати " +"псевдоніми до своєї адреси електронної пошти. Необхідні псевдоніми, такі як " +"\"postmaster\", створюються автоматично, вказуючи на першого користувача-" +"адміністратора." -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." @@ -1982,7 +2016,7 @@ msgstr "" "Застосунок Roundcube надає " "вебінтерфейс для доступу користувачів до ел. пошти." -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2112,7 +2146,7 @@ msgstr "Порт" msgid "Host/Target/Value" msgstr "Хост/ціль/значення" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2123,7 +2157,7 @@ msgstr "" "трафік Вашого {box_name}. Тримайте фаєрвол увімкненим і належно " "налаштованим, це зменшить ризик загроз безпеці з Інтернету." -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "Фаєрвол" @@ -2143,48 +2177,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "Порт {name} ({details}) недоступний для зовнішніх мереж" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "Сервіс/Порт" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "Дозволено" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "Вимкнено" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "Дозволяється" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "Дозволяється (лише внутрішні)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "Дозволяється (лише зовнішні)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "Блоковано" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2194,13 +2219,13 @@ msgstr "" "дозволений у фаєрволі і якщо Ви вимкнете сервіс, він також буде вимкнений у " "фаєрволі." -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "Розширені" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2215,10 +2240,13 @@ msgid "" "also be obtained by running the command \"sudo cat /var/lib/plinth/firstboot-" "wizard-secret\" on your {box_name}" msgstr "" +"Введіть таємний код, утворений під час установлення FreedomBox. Цей таємний " +"код також можна отримати, виконавши команду \"sudo cat /var/lib/plinth/" +"firstboot-wizard-secret\" на вашому {box_name}" #: plinth/modules/first_boot/forms.py:19 msgid "Firstboot Wizard Secret" -msgstr "" +msgstr "Асистент під час першого завантаження" #: plinth/modules/first_boot/templates/firstboot_complete.html:11 msgid "Setup Complete!" @@ -2250,7 +2278,7 @@ msgstr "Розпочати встановлення" msgid "Setup Complete" msgstr "Налаштування завершено" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2268,7 +2296,7 @@ msgstr "" "термінальний клієнт для Git або через різні доступні графічні клієнти. І Ви " "можете ділитися своїм кодом із людьми по всьому світу." -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." @@ -2276,68 +2304,68 @@ msgstr "" "Щоб дізнатися більше про те, як користуватися Git відвідайте навчання Git." -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "Доступ до читання-запису репозиторіїв Git" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "Gitweb" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "Просте розміщення Git" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "Некоректна URL-адреса репозиторію." -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "Некоректна назва репозиторію." -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" "Назва нового репозиторію або URL для імпортування зовнішнього репозиторію." -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "Опис репозиторію" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "Необовʼязково, для відображення на Gitweb." -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "Імʼя власника репозиторію" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "Приватний репозиторій" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "Дозволити доступ до цього репозиторію лише авторизованим користувачам." -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "Репозиторій із цією назвою вже існує." -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "Назва репозиторію" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "Рядок із букв і чисел, що унікально ідентифікує репозиторій." -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "Типова гілка" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "Gitweb відображає це як типову гілку." @@ -2381,19 +2409,19 @@ msgstr "Видалити Git-репозиторій %(name)s" msgid "Delete this repository permanently?" msgstr "Видалити цей репозиторій безповоротно?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "Репозиторій створено." -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "Помилка відбулася під час створення репозиторію." -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "Репозиторій змінено." -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "Змінити репозиторій" @@ -2529,6 +2557,11 @@ msgid "" "into your language, hosting hackathons or install fests, and by spreading " "the word." msgstr "" +"Ви можете зробити свій внесок, пишучи код, тестуючи та повідомляючи про " +"помилки, обговорюючи нові варіанти використання та застосунки, розробляючи " +"логотипи та ілюстрації, надаючи підтримку своїм колегам-користувачам, " +"перекладаючи FreedomBox та його застосунки на вашу мову, проводячи хакатони " +"або фестивалі встановлення, а також поширюючи відомості про FreedomBox." #: plinth/modules/help/templates/help_contribute.html:28 msgid "" @@ -2541,6 +2574,14 @@ msgid "" "throughout the world. The FreedomBox Foundation would not exist without its " "supporters." msgstr "" +"Ви також можете допомогти проєкту фінансово, зробивши пожертву на рахунок неприбуткової " +"організації FreedomBox Foundation. Заснована у 2011 році, FreedomBox " +"Foundation є неприбутковою організацією зі статусом 501(c)(3) зі штаб-" +"квартирою у Нью-Йорку, яка існує для підтримки проєкту FreedomBox. Вона " +"забезпечує технічну інфраструктуру та юридичні послуги для проєкту, розвиває " +"партнерські відносини та виступає на захист FreedomBox у всьому світі. " +"Фундація FreedomBox не існувала б без своїх прихильників." #: plinth/modules/help/templates/help_contribute.html:42 #: plinth/modules/power/templates/power_restart.html:27 @@ -2558,6 +2599,9 @@ msgid "" "Below is a list of opportunities for contributing to Debian. It has been " "filtered to only show packages that are installed on this system." msgstr "" +"Нижче наведено список можливостей для сприяння розвитку Debian. Він був " +"відфільтрований, щоб показати лише ті пакунки, які встановлено на цій " +"системі." #: plinth/modules/help/templates/help_contribute.html:59 msgid "Show issues" @@ -2578,11 +2622,11 @@ msgstr "Пакунки, яких нема в Debian testing" #: plinth/modules/help/templates/help_contribute.html:92 msgid "Good first issues for beginners" -msgstr "" +msgstr "Перші проблеми для початківців" #: plinth/modules/help/templates/help_contribute.html:104 msgid "Issues for which the package maintainer has requested help" -msgstr "" +msgstr "Проблеми, за якими супровідник пакета звернувся за допомогою" #: plinth/modules/help/templates/help_feedback.html:12 #, python-format @@ -2647,6 +2691,11 @@ msgid "" "\"> mailing list. The list archives also contain information about " "problems faced by other users and possible solutions." msgstr "" +"Для звернення за допомогою до спільноти %(box_name)s запити можуть бути " +"розміщені в списку розсилки. В архівах списку також містяться " +"відомості про проблеми, з якими стикалися інші користувачі, та можливі шляхи " +"їх вирішення." #: plinth/modules/help/templates/help_index.html:40 #, python-format @@ -2656,6 +2705,10 @@ msgid "" "oftc.net/?randomnick=1&channels=freedombox&prompt=1\"> #freedombox " "channel using the IRC web interface." msgstr "" +"Багато дописувачів та користувачів %(box_name)s також доступні в IRC-мережі " +"irc.oftc.net. Приєднуйтесь та звертайтеся за допомогою на каналі #freedombox за допомогою вебінтерфейсу IRC." #: plinth/modules/help/templates/help_manual.html:18 msgid "Download as PDF" @@ -2733,7 +2786,7 @@ msgstr "Про {box_name}" msgid "{box_name} Manual" msgstr "Посібник для {box_name}" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2745,7 +2798,7 @@ msgstr "" "надсилаючи зашифрований трафік через волонтерську мережу, розподілену по " "всьому світу." -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2753,26 +2806,26 @@ msgstr "" "Детальніше про I2P на їхній домашній сторінці проєкту." -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" "Перше відвідування наданого вебінтерфейсу розпочне процес налаштування." -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "Керування застосунком I2P" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "I2P" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "Мережа анонімності" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "Проксі I2P" @@ -2795,12 +2848,17 @@ msgid "" "For this, your browser, preferably the Tor Browser, needs to be configured " "with a proxy." msgstr "" +"I2P дозволяє анонімно переглядати Інтернет та приховані служби (eepsites). " +"Для цього ваш браузер, бажано Tor Browser, повинен бути налаштований з " +"проксі-сервером." #: plinth/modules/i2p/views.py:19 msgid "" "By default HTTP, HTTPS and IRC proxies are available. Additional proxies and " "tunnels may be configured using the tunnel configuration interface." msgstr "" +"Типово доступні HTTP, HTTPS та IRC проксі-сервери. Додаткові проксі-сервери " +"та тунелі можна налаштувати за допомогою інтерфейсу налаштування тунелів." #: plinth/modules/i2p/views.py:24 msgid "" @@ -2808,8 +2866,11 @@ msgid "" "network. Download files by adding torrents or create a new torrent to share " "a file." msgstr "" +"I2P надає застосунок для анонімного завантаження файлів в піринговій мережі. " +"Завантажуйте файли, додаючи торенти або створюйте новий торент, щоб " +"поділитися файлом." -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2819,7 +2880,7 @@ msgstr "" "легких мов розмітки, включаючи Markdown, та основні функції для роботи з " "блоґами, як-от коментарі та стрічки RSS." -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2833,15 +2894,15 @@ msgstr "" "\"{users_url}\">налаштуваннях користувача Ви можете змінити ці права або " "додавати нових користувачів." -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Вікі та блоґ" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "Перегляд і редагування застосунків вікі" @@ -2894,42 +2955,44 @@ msgid "" "This action will remove all the posts, pages and comments including revision " "history. Delete this wiki or blog permanently?" msgstr "" +"Ця дія видалить всі дописи, сторінки та коментарі, включаючи історію " +"редагувань. Видалити цю вікі чи блог назавжди?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "Створено вікі {name}." -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "Не можливо створити вікі: {error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "Створено блоґ {name}." -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "Не можливо створити блоґ: {error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} видалено." -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "Не можливо видалити {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted — це сервер для Gobby, колективного редактора тексту." -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2940,11 +3003,11 @@ msgstr "" "Gobby, стільничний клієнт і встановіть їх. Потім запустіть Gobby, " "виберіть «Зʼєднатися зі сервером» і введіть Вашу доменну назву {box_name}." -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "infinoted" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Сервер Gobby" @@ -2992,7 +3055,7 @@ msgstr "Відеокімната Janus" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "Інформація про ліцензію JavaScript" @@ -3012,7 +3075,7 @@ msgstr "JSXC" msgid "Chat Client" msgstr "Клієнт чату" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -3021,24 +3084,34 @@ msgid "" "domain. It does so by proving itself to be the owner of a domain to Let's " "Encrypt, a certificate authority (CA)." msgstr "" +"Цифровий сертифікат дозволяє користувачам мережевої служби перевіряти " +"ідентичність служби та безпечно спілкуватися з нею. {box_name} може " +"автоматично отримувати та налаштовувати цифрові сертифікати для кожного " +"доступного домену. Для цього він підтверджує, що є власником домену в Let's " +"Encrypt, центрі сертифікації (ЦС)." -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " "read and agree with the Let's Encrypt Subscriber Agreement before using this service." msgstr "" +"Let's Encrypt - це вільний, автоматизований і відкритий центр сертифікації, " +"який працює в інтересах громадськості під керівництвом Internet Security " +"Research Group (ISRG). Будь ласка, ознайомтеся та погодьтеся з Угодою підписувача Let's Encrypt " +"перед тим, як користуватися цією службою." -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "Сертифікати" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "Тестування не можливе: Нема налаштованих доменів." @@ -3103,7 +3176,7 @@ msgstr "" "Нема налаштованих доменів. Налаштуйте домени, " "щоб мати можливість отримати сертифікати для них." -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " @@ -3112,34 +3185,34 @@ msgstr "" "Сертифікат успішно відкликано для домена {domain}. Це може зайняти кілька " "хвилин, перш ніж почне діяти." -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "Не вдалося відкликати сертифікат для домену {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "Сертифікат успішно отримано для домену {domain}" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "Не вдалося отримати сертифікат для домену {domain}: {error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "Сертифікат успішно видалено для домену {domain}" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "Не вдалося видалити сертифікат для домену {domain}: {error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3156,7 +3229,7 @@ msgstr "" "можуть спілкуватися з користувачами на інших серверах Matrix через " "федеративність." -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " @@ -3166,7 +3239,7 @@ msgstr "" "Встановіть програму Coturn або налаштуйте " "зовнішній сервер." -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3180,6 +3253,9 @@ msgid "" "a new account on your Matrix server. Disable this if you only want existing " "users to be able to use it." msgstr "" +"Увімкнення публічної реєстрації означає, що будь-хто в Інтернеті може " +"зареєструвати новий обліковий запис на вашому сервері Matrix. Вимкніть цю " +"функцію, якщо ви хочете, щоб нею могли користуватися лише наявні користувачі." #: plinth/modules/matrixsynapse/forms.py:24 #, python-brace-format @@ -3188,6 +3264,9 @@ msgid "" "server for Matrix Synapse. Disable this if you want to use a different STUN/" "TURN server." msgstr "" +"Конфігурує локальний застосунокcoturn як сервер " +"STUN/TURN для Matrix Synapse. Вимкніть цю опцію, якщо ви хочете " +"використовувати інший сервер STUN/TURN." #: plinth/modules/matrixsynapse/manifest.py:14 msgid "Element" @@ -3209,6 +3288,10 @@ msgid "" "servers will be able to reach users on this server using this domain name. " "Matrix user IDs will look like @username:domainname." msgstr "" +"Служба Matrix повинна бути налаштована для домену. Користувачі на інших " +"серверах Matrix зможуть звертатися до користувачів на цьому сервері, " +"використовуючи це доменне ім'я. Ідентифікатори користувачів Matrix матимуть " +"вигляд @ім'я_користувача:назва_домену." #: plinth/modules/matrixsynapse/templates/matrix-synapse-pre-setup.html:26 msgid "" @@ -3255,7 +3338,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3267,7 +3350,7 @@ msgstr "" "вебсайту. Ви можете використовувати MediaWiki для розміщення вебсайту на " "зразок вікі, робити нотатки або співпрацювати з друзями над проєктами." -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3281,7 +3364,7 @@ msgstr "" "користувачів із самої MediaWiki перейшовши на сторінку Special:CreateAccount." -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." @@ -3289,12 +3372,12 @@ msgstr "" "Будь-хто, хто має посилання на цю вікі може читати її. Лише користувачі, що " "ввійшли можуть робити зміни вмісту." -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "MediaWiki" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "Вікі" @@ -3375,35 +3458,35 @@ msgstr "Пароль оновлено" msgid "Password update failed. Please choose a stronger password" msgstr "Не вдалося оновити пароль. Оберіть сильніший пароль" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "Публічні реєстрації дозволено" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "Публічні реєстрації вимкнено" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "Приватний режим дозволено" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "Приватний режим вимкнено" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "Типову шкурку змінено" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "Доменну назву оновлено" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "Назву сайту оновлено" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3416,11 +3499,11 @@ msgstr "" "портом (30000). Щоб підʼєднатися до сервера потрібено клієнт Minetest." -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "Minetest" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "Блокова пісочниця" @@ -3470,7 +3553,7 @@ msgstr "" msgid "Address" msgstr "Адреса" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3633,7 +3716,7 @@ msgstr "Захищена оболонка" msgid "Services" msgstr "Сервіси" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." @@ -3641,7 +3724,7 @@ msgstr "" "Налаштування мережевих пристроїв. Зʼєднання з Інтернетом через Ethernet, Wi-" "Fi або PPPoE. Ділитися цим зʼєднанням з іншими пристроями в мережі." -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." @@ -3649,7 +3732,7 @@ msgstr "" "Пристрої, що адмініструються іншими способами, можуть бути недоступними для " "налаштування тут." -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "Мережі" @@ -4045,7 +4128,7 @@ msgstr "Змінити зʼєднання" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "Зміни" @@ -4150,7 +4233,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "Метод" @@ -4166,7 +4249,7 @@ msgstr "Сервер DNS" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "Типово" @@ -4179,7 +4262,7 @@ msgid "This connection is not active." msgstr "Це зʼєднання неактивне." #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "Безпека" @@ -4744,7 +4827,7 @@ msgstr "Зʼєднання {name} видалено." msgid "Failed to delete connection: Connection not found." msgstr "Не вдалося видалити зʼєднання: Зʼєднання не знайдено." -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4755,20 +4838,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "Підʼєднання до сервісів VPN" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "Віртуальна приватна мережа" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4779,61 +4862,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "Профіль" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "Завантажити мій профіль" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4842,19 +4893,19 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" "{box_name} підʼєднано до (бездротового) маршрутизатора, яким Ви не можете " "керувати." -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." @@ -4862,7 +4913,7 @@ msgstr "" "Ваш постачальник Інтернет-послуг не надає Вам зовнішньої IP-адреси, а надає " "Інтернет-зʼєднання через NAT." -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." @@ -4870,11 +4921,11 @@ msgstr "" "Ваш постачальник Інтернет-послуг не надає Вам статичної IP-адреси і Ваша IP-" "адреса змінюється кожного разу, коли Ви підʼєднуєтеся до Інтернету." -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "Ваш ISP обмежує вхідні зʼєднання." -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4883,23 +4934,23 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "Публічна видимість" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "Домен PageKite" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "Домен сервера" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -4907,65 +4958,65 @@ msgstr "" "Виберіть Ваш сервер для pagekite. Вкажіть \"pagekite.net\", щоб " "використовувати типовий сервер pagekite.net." -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "Порт сервера" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "Порт Вашого сервера pagekite (типово: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Назва kite" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "Приклад: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "Неправильна назва kite" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "протокол" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "зовнішній порт (frontend)" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "внутрішній порт (feedombox)" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "Дозволити піддомени" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "Видалено власний сервіс" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "Цей сервіс уже доступний як стандартний сервіс." -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "Додано власний сервіс" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "Цей сервіс вже існує" @@ -4999,29 +5050,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Вебсервер (HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "Сайт буде доступний за адресою http://{0}" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Вебсервер (HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "Сайт доступний за адресою https://{0}" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "Захищена оболонка (SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -5065,8 +5116,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "Перезапустити" @@ -5112,6 +5163,39 @@ msgstr "" msgid "Shut Down Now" msgstr "Вимкнути зараз" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -5143,7 +5227,7 @@ msgstr "Веб-проксі" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -5160,7 +5244,7 @@ msgstr "" "один чи більше клієнтів Quassel для приєднання чи відʼєднання з настільного " "ПК чи мобільного." -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your настільного ПК " "і мобільного." -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "Quassel" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "Клієнт IRC" @@ -5183,7 +5267,7 @@ msgstr "Клієнт IRC" msgid "Quasseldroid" msgstr "Quasseldroid" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -5198,19 +5282,19 @@ msgstr "" "\">підтримувані клієнтські застосунки. До Radicale може мати доступ будь-" "який користувач з імʼям входу для {box_name}." -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "Radicale" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "Календар і адресна книга" @@ -5274,7 +5358,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "Оновлено налаштування прав доступу" @@ -5318,8 +5402,8 @@ msgstr "" "облікового запису Google і сервером – imaps://imap.gmail.com. " "Зауважте, що потрібно дозволити «Малозахищені додатки» в налаштуваннях " "облікового запису Google (https://www.google.com/settings/security/" -"lesssecureapps)." +"lesssecureapps\">https://www.google.com/settings/security/lesssecureapps)." #: plinth/modules/roundcube/__init__.py:50 msgid "Email Client" @@ -5365,7 +5449,7 @@ msgstr "" "RSS для відстеження різних вебсайтів. Під час додавання стрічки " "дозвольте автентифікацію і використовуйте свої облікові дані {box_name}." -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "Читати і підписатися на стрічки новин" @@ -5378,13 +5462,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "Ґенератор стрічок RSS" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5393,31 +5477,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "Доступ до приватних поширень" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "Samba" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "Мережеве сховище файлів" @@ -5495,15 +5579,15 @@ msgstr "" msgid "Action" msgstr "Дія" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "Диск ОС FreedomBox" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5529,7 +5613,7 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "Помилка вимкнення поширення: {error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." @@ -5537,7 +5621,7 @@ msgstr "" "Searx — це система збірного пошуку в Інтернеті, яка поважає приватність. " "Вона збирає і відображає результати з різних пошукових систем." -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." @@ -5545,40 +5629,40 @@ msgstr "" "Searx може використовуватися для обходу стеження та профілювання пошуковими " "системами." -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "Пошук в Інтернеті" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "Searx" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Вебпошук" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "Безпечний пошук" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" "Вибрати типовий сімейний фільтр для застосування до Ваших результатів пошуку." -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "Модерований" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "Строгий" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "Дозволити публічний доступ" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" "Дозволити користуватися цим застосуноком кожному, хто має до нього доступ." @@ -5740,14 +5824,14 @@ msgstr "Закладки" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5756,48 +5840,48 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "Проксі Socks5" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "Рекомендоване" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "Сервер" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "Назва хоста сервера або IP-адреса" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "Номер порта сервера" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" "Пароль, що використовується для шифрування даних. Має відповідати паролю " "сервера." -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "Метод шифрування. Має відповідати налаштуванням на сервері." -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " @@ -5806,15 +5890,15 @@ msgstr "" "Обмін дозволяє Вам обмінюватися файлами і теками з Вашого {box_name}, через " "Інтернет, до обраної групи користувачів." -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "Обмін" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "Назва ділянки" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." @@ -5822,37 +5906,37 @@ msgstr "" "Рядок з малих літер та цифр, що унікально позначає ділянку. Приклад: " "media." -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "Шлях до ділянки" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "Шлях до теки на сервері, якою Ви маєте намір ділитися." -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "Публічна ділянка" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "Зробіть файли в теці доступними для будь-кого за посиланням." -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "Групи користувачів, які можуть зчитувати файли з ділянки:" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "Користувачі вибраних груп зможуть читати файли цієї ділянки." -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "Ділянка з такою назвою вже існує." -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "Ділянка має бути спільною або публічною для щонайменше однієї групи" @@ -5889,19 +5973,19 @@ msgstr "Ділянку додано." msgid "Add Share" msgstr "Додати ділянку" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "Ділянку змінено." -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "Змінити ділянку" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "Ділянку видалено." -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -5911,7 +5995,7 @@ msgstr "" "можна використовувати для відкочування системи до попереднього хорошого " "стану в разі небажаних змін системи." -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5922,7 +6006,7 @@ msgstr "" "встановлення ПЗ. Старі зрізи автоматично видалятимуться відповідно до " "налаштувань нижче." -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for резервних копій, поки вони " "не зберігаються на одному розділі. " -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "Зрізи сховища" @@ -6035,7 +6119,7 @@ msgstr "Дата" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "Видалити зріз" @@ -6083,57 +6167,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "створено вручну" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "за часом" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "apt" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "Керування зрізами" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "Створено зріз." -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "Налаштування зрізів сховища оновлено" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "Помилка дії: {0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "Видалити вибрані зрізи" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "Зріз зараз використовується. Повторіть пізніше." -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "Відкочено до зрізу #{number}." -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "Систему потрібно перезапустити, щоб завершити відкат." -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -6145,7 +6229,7 @@ msgstr "" "виконувати завдання з адміністрування, копіювання файлів або запускати інші " "сервіси через певні зʼєднання." -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "Сервер захищеної оболонки (SSH)" @@ -6183,14 +6267,6 @@ msgstr "Алґоритм" msgid "Fingerprint" msgstr "Відбиток" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "автентифікація SSH із вимкненим паролем." - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "автентифікація SSH із дозволеним паролем." - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -6203,7 +6279,7 @@ msgstr "Вхід" msgid "Logged out successfully." msgstr "Вийшли успішно." -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -6214,145 +6290,145 @@ msgstr "" "{box_name}. Під час використання сховище даних можна переглядати, монтувати " "і відмонтовувати знімні накопичувачі, розширювати розділ root тощо." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "Сховище" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} байтів" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} КБ" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} МБ" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} ГБ" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} ТБ" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "Операція невдала." -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "Операцію скасовано." -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Пристрій вже відмонтований." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "Час операції вийшов." -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "Операція вже була скасована." -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Пристрій уже змонтовано." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Пристрій не змонтовано." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Пристрій змонтовано іншим користувачем." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" "Мало простору в розділі системи: {percent_used}% використано, {free_space} " "вільно." -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "Мало простору на диску" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "Некоректна назва каталогу." -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "Каталог не існує." -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "Шлях не є каталогом." -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "Каталог не може читатися користувачем." -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "Каталог не може записуватися користувачем." -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "Каталог" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "Підкаталог (необовʼязково)" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "Інший каталог (вкажіть нижче)" @@ -6386,7 +6462,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "Розширити кореневий розділ" @@ -6406,30 +6482,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "Помилка розширення розділу: {exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "Розділ успішно розширено." -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "{drive_vendor} {drive_model} можна безпечно відʼєднувати." -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "Пристрій можна безпечно витягати." -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "Помилка виймання пристрою: {error_message}" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6437,7 +6513,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6449,20 +6525,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "Адміністрування програми Syncthing" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "Syncthing" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "Синхронізація файлів" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6475,7 +6551,7 @@ msgstr "" "під час вебсерфінгу, проєкт Tor радить використовувати Tor Browser." -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " @@ -6483,40 +6559,40 @@ msgid "" msgstr "" "Порт SOCKS для Tor на Вашому {box_name} для внутрішніх мереж – TCP 9050." -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "Tor" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Сервіс Tor Onion" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6614,11 +6690,11 @@ msgstr "Сервіс Onion" msgid "Ports" msgstr "Порти" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "Оновлення налаштувань" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "Помилка налаштування застосунку: {error}" @@ -6676,7 +6752,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -6686,7 +6762,7 @@ msgstr "" "спроєктований читати новини з будь-яких місць, при цьому намагається бути " "максимально близьким до стільничної програми, на скільки це можливо." -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -6695,7 +6771,7 @@ msgstr "" "Якщо дозволено, Tiny Tiny RSS може бути доступним для будь-якого користувача, що належить до групи feed-reader." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." @@ -6703,11 +6779,11 @@ msgstr "" "Коли використовуєте мобільний або стільничний застосунок для Tiny Tiny RSS, " "використовуйте URL /tt-rss-app для зʼєднання." -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "Tiny Tiny RSS" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "Читання новинних стрічок" @@ -6715,12 +6791,12 @@ msgstr "Читання новинних стрічок" msgid "Tiny Tiny RSS (Fork)" msgstr "Tiny Tiny RSS (відгілка)" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "Перевірити і застосувати останні оновлення безпеки і ПЗ." -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6728,33 +6804,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "Оновлення ПЗ" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox оновлено" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "Не можливо запустити оновлення дистрибутиву" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "Оновлення дистрибутиву розпочато" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6923,44 +6999,44 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "Тестувати оновлення дистрибутиву зараз" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "Дозволено автоматичні оновлення" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "Вимкнено автоматичні оновлення" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "Дозволено оновлення дистрибутиву" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "Вимкнено оновлення дистрибутиву" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "Процес оновлення розпочато." -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "Не вдалося розпочати оновлення." -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "Оновлення частих можливостей активовано." -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "Запуск тесту оновлення дистрибутиву." -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " @@ -6971,7 +7047,7 @@ msgstr "" "застосунки також вимагають, щоб обліковий запис був частиною групи, щоб " "отримати авторизований доступ до застосунку." -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6983,15 +7059,15 @@ msgstr "" "користувачі з групи admin можуть змінювати застосунки або системні " "налаштування." -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "Користувачі і групи" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "Доступ до всіх сервісів і налаштувань системи" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "Перевірка запису LDAP \"{search_item}\"" @@ -7010,11 +7086,11 @@ msgid "" msgstr "" "Обовʼязково. 150 знаків, не більше. Лише англійські букви, цифри і @/./-/_." -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "Пароль для авторизації" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." @@ -7022,11 +7098,11 @@ msgstr "" "Уведіть пароль для користувача \"{user}\", щоб авторизувати зміни облікового " "запису." -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "Неправильний пароль." -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -7040,12 +7116,12 @@ msgstr "" "входити в усі сервіси. Вони також можуть входити в систему через SSH і мати " "адміністративні права (sudo)." -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "Не вдалося створити користувача LDAP: {error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "Не вдалося додати нового користувача до групи {group}: {error}" @@ -7064,41 +7140,41 @@ msgstr "" "систему без використання пароля. Ви можете вказати декілька ключів, один на " "кожен рядок. Порожні рядки і рядки, що починаються на # іґноруються." -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "Не вдалося перейменувати користувача LDAP." -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "Не вдалося вилучити користувача з групи." -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "Не вдалося додати користувача до групи." -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "Не можливо задати ключі SSH." -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "Не вдалося змінити стан користувача." -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "Не вдалося змінити пароль користувача LDAP." -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "Не вдалося додати нового користувача до адмінської групи: {error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "Не вдалося обмежити доступ до консолі: {error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "Обліковий запис користувача створено, Ви ввійшли в систему" @@ -7115,12 +7191,12 @@ msgstr "Зберегти пароль" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "Створити користувача" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "Видалити користувача" @@ -7161,17 +7237,17 @@ msgid "The following administrator accounts exist in the system." msgstr "Наступні облікові записи адміністратора існують у системі." #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "Користувачі" @@ -7204,34 +7280,34 @@ msgstr "" msgid "Save Changes" msgstr "Зберегти зміни" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "Створено користувача %(username)s." -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "Користувача %(username)s оновлено." -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "Зміни користувача" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "Користувача {user} видалено." -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "Не вдалося видалити користувача LDAP." -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "Зберегти пароль" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "Пароль змінено успішно." @@ -7547,7 +7623,7 @@ msgstr "Видалити зʼєднання до сервера" msgid "Server deleted." msgstr "Сервер видалено." -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7556,7 +7632,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7565,26 +7641,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "Вебсайт і блоґ" @@ -7598,7 +7674,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7620,7 +7696,7 @@ msgstr "" "календарного перегляду. Окремими світлинами можна ділитися з іншими, " "надіславши пряме посилання." -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7631,11 +7707,11 @@ msgstr "" "Для додаткових користувачів потрібно створити облікові записи і в " "{box_name}, і в Zoph з тим же іменем користувача." -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "Zoph" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "Упорядник світлин" @@ -7686,96 +7762,92 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "Пакунок {package_name} має останню версію ({latest_version})" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "Помилка запуску apt-get" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "встановлення" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "завантаження" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "зміна медія" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "файл конфіґурації: {file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "Встановлення застосунку" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "Оновлення застосунку" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "Помилка встановлення застосунку: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "Помилка оновлення застосунку: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "Помилка встановлення застосунку: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "Помилка оновлення застосунку: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "Застосунок встановлено." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "Застосунок оновлено" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "Видалення застосунку" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "Помилка видалення застосунку: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "Помилка видалення застосунку: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "Застосунок видалено." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "Оновлення пакунків застосунків" @@ -7834,53 +7906,54 @@ msgstr "Встановлення" msgid "Service %(service_name)s is not running." msgstr "Сервіс %(service_name)s не запущено." -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "Функціональність ядра та вебінтерфейс для %(box_name)s" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " Домівка" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "Домівка" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " Застосунки" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "Застосунки" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " Система" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "Система" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "Змінити пароль" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "Вимкнути" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "Вийти" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "Вибрати мову" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "Увійти" @@ -8167,6 +8240,38 @@ msgstr "перед видаленням {app_id}" msgid "Gujarati" msgstr "Gujarati" +#~ msgid "Enable DNSSEC" +#~ msgstr "Увімкнути DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Дозволити розширення безпеки системи доменних назв" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "Демон фаєрвола не запущено. Будь ласка, запустіть його. Фаєрвол увімкнено " +#~ "типово на %(box_name)s. У будь-якій системі на основі Debian (наприклад, " +#~ "%(box_name)s) ви можете запустити його за допомогою команди 'service " +#~ "firewalld start' або у випадку системи з systemd 'systemctl start " +#~ "firewalld'." + +#~ msgid "SSH authentication with password disabled." +#~ msgstr "автентифікація SSH із вимкненим паролем." + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "автентифікація SSH із дозволеним паролем." + +#~ msgid "Error running apt-get" +#~ msgstr "Помилка запуску apt-get" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "Функціональність ядра та вебінтерфейс для %(box_name)s" + #~ msgid "Network Connections" #~ msgstr "Мережеві зʼєднання" diff --git a/plinth/locale/vi/LC_MESSAGES/django.po b/plinth/locale/vi/LC_MESSAGES/django.po index b299b8a36..349c16aa5 100644 --- a/plinth/locale/vi/LC_MESSAGES/django.po +++ b/plinth/locale/vi/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-07-28 08:34+0000\n" "Last-Translator: bruh \n" "Language-Team: Vietnamese calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1055,29 +1048,29 @@ msgstr "" "ứng dụng. Tất cả người dùng có quyền truy cập đều có thể sử dụng tất cả các " "thư viện." -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "Sử dụng thư viện sách điện tử của calibre" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "Thư viện sách điện tử" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "Tên của thư viện mới" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "Một thư viện có tên này đã tồn tại." @@ -1125,20 +1118,20 @@ msgstr "Đi đến thư viện %(library)s" msgid "Delete library %(library)s" msgstr "Xoá thư viện %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "Đã tạo thư viện." -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "Đã xảy ra lỗi trong khi tạo thư viện." -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "Đã xoá {name}." -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "Không thể xoá {name}: {error}" @@ -1186,7 +1179,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "Quản trị máy chủ" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1194,18 +1187,18 @@ msgstr "" "Ở đây bạn có thể đặt một số tùy chọn thiết lập chung như tên máy chủ, tên " "miền, trang chủ của máy chủ web, v.v." -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "Thiết lập chung" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "Thiết lập" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1317,47 +1310,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "Lỗi khi đặt tên máy chủ: {exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "Đã đặt tên máy chủ" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "Lỗi khi đặt tên miền: {exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "Đã đặt tên miền" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "Lỗi khi đặt trang chủ của máy chủ web: {exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "Đã đặt trang chủ của máy chủ web" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "Lỗi khi thay đổi chế độ nâng cao: {exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "Đang hiện các ứng dụng và tính năng nâng cao" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "Đang ẩn các ứng dụng và tính năng nâng cao" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1369,7 +1362,7 @@ msgstr "" "các máy chủ giao tiếp khác có thể sử dụng nó để thiết lập một cuộc gọi giữa " "các bên mà không thể kết nối với nhau nếu không có nó." -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as ejabberd cần phải được thiết lập với các chi tiết được cung " "cấp ở đây." -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "Trợ giúp cho VoIP" @@ -1442,11 +1435,11 @@ msgstr "Lỗi khi đặt múi giờ: {exception}" msgid "Time zone set" msgstr "Đã đặt múi giờ" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge là một ứng dụng khách cho BitTorrent, nó có một Giao diện Web." -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." @@ -1454,16 +1447,16 @@ msgstr "" "Mật khẩu mặc định là 'deluge', nhưng bạn nên đăng nhập và đổi nó ngay lập " "tức sau khi bật dịch vụ này." -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "Tải các tệp xuống bằng các ứng dụng BitTorrent" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "Ứng dụng khách trên web cho BitTorrent" @@ -1589,7 +1582,7 @@ msgstr "Kết quả" msgid "Diagnostic Test" msgstr "Kiểm tra chẩn đoán" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1600,7 +1593,7 @@ msgstr "" "24h), những người khác có thể khó tìm bạn trên Internet. Việc này sẽ ngăn " "những người khác tìm các dịch vụ được {box_name} này cung cấp." -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1617,7 +1610,7 @@ msgstr "" "phân tên DNS của bạn cho IP mới, và nếu ai đó từ Internet hỏi tên DNS của " "bạn, họ sẽ nhận một phản hồi với địa chỉ IP hiện tại của bạn." -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 #, fuzzy #| msgid "" #| "If you are looking for a free dynamic DNS account, you may find a free " @@ -1637,11 +1630,11 @@ msgstr "" "phí dựa trên URL cập nhật tại freedns.afraid.org." -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "Ứng dụng khách DNS động" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "Tên miền động" @@ -1775,7 +1768,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1840,13 +1833,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1970,14 +1963,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1985,7 +1978,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1995,13 +1988,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2142,7 +2135,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2150,7 +2143,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -2170,61 +2163,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2270,7 +2254,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2281,73 +2265,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2391,19 +2375,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2696,7 +2680,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2704,31 +2688,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2765,14 +2749,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2781,15 +2765,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2843,41 +2827,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2885,11 +2869,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2935,7 +2919,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2953,7 +2937,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2963,7 +2947,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2971,15 +2955,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -3042,41 +3026,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3086,14 +3070,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -3174,7 +3158,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3182,7 +3166,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3191,18 +3175,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3273,39 +3257,39 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "Đã đặt tên miền" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "Đã đặt tên miền" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3314,11 +3298,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3363,7 +3347,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3524,19 +3508,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3882,7 +3866,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3987,7 +3971,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -4003,7 +3987,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -4016,7 +4000,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4552,7 +4536,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4563,20 +4547,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4586,61 +4570,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4649,33 +4601,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4684,87 +4636,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4798,29 +4750,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4862,8 +4814,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4905,6 +4857,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4936,7 +4919,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4947,7 +4930,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4967,7 +4950,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4977,19 +4960,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -5048,7 +5031,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -5120,7 +5103,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5133,13 +5116,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5148,31 +5131,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5250,15 +5233,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5284,51 +5267,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5481,14 +5464,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5497,97 +5480,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5624,26 +5607,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5651,14 +5634,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5752,7 +5735,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5800,57 +5783,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5858,7 +5841,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5891,14 +5874,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5911,7 +5886,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5922,143 +5897,143 @@ msgstr "" "của bạn. Bạn có thể xem phương tiện lưu trữ hiện đang sử dụng, gắn và bỏ gắn " "phương tiện có thể rút ra, mở rộng phân vùng root, v.v." -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "Thiết bị này đã đang bỏ gắn rồi." -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "Đang thử bỏ gắn một thiết bị đang bận." -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "Thiết bị này đã được gắn rồi." -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "Thiết bị này chưa được gắn." -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "Thiết bị này được một người dùng khác gắn." -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6092,7 +6067,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -6110,30 +6085,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6141,7 +6116,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6153,20 +6128,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6175,47 +6150,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6313,13 +6288,13 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "Đã xảy ra lỗi trong khi thiết lập." -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6377,14 +6352,14 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "It can be accessed by any user on {box_name} " @@ -6396,17 +6371,17 @@ msgstr "" "Nó có thể được truy cập bởi bất kỳ người dùng nào trên {box_name} thuộc về nhóm admin." -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6414,12 +6389,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6427,33 +6402,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6601,51 +6576,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6653,15 +6628,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6679,21 +6654,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6702,12 +6677,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6723,41 +6698,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6774,12 +6749,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6817,17 +6792,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6858,34 +6833,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7194,7 +7169,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7203,7 +7178,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7212,26 +7187,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7245,7 +7220,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7258,7 +7233,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7266,11 +7241,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7320,110 +7295,104 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "Lỗi trong khi sao lưu" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "Lỗi khi cài đặt ứng dụng: {string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "Lỗi khi cài đặt ứng dụng: {string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "Lỗi khi cài đặt ứng dụng: {error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "Lỗi khi cài đặt ứng dụng: {error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "Ứng dụng đã được cài đặt." -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "Lỗi khi cài đặt ứng dụng: {error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "Lỗi khi cài đặt ứng dụng: {string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "Lỗi khi cài đặt ứng dụng: {error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "Ứng dụng đã được cài đặt." -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7474,53 +7443,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -7785,6 +7755,17 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "Bật DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "Bật Phần mở rộng bảo mật cho Hệ thống tên miền" + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "Lỗi trong khi sao lưu" + #~ msgid "" #~ "Cockpit requires that you access it through a domain name. It will not " #~ "work when accessed using an IP address as part of the URL." diff --git a/plinth/locale/zh_Hans/LC_MESSAGES/django.po b/plinth/locale/zh_Hans/LC_MESSAGES/django.po index 413acf63c..e1fa24f81 100644 --- a/plinth/locale/zh_Hans/LC_MESSAGES/django.po +++ b/plinth/locale/zh_Hans/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Plinth\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2022-09-03 14:18+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -998,29 +991,29 @@ msgstr "" "只有属于calibre组的用户才能够访问该应用程序。所有有权限的用户都可以" "使用所有的图书馆。" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "使用 calibre 电子书库" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "电子书库" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "新库名称" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "已存在同名的库。" @@ -1066,20 +1059,20 @@ msgstr "转到库%(library)s" msgid "Delete library %(library)s" msgstr "删除站点 %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "创建了库。" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "在创建库时发生了一个错误。" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} 已删除。" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "不能删除 {name}:{error}" @@ -1123,24 +1116,24 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "服务器管理" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." msgstr "在这里你可以设置一些一般的配置选项,如主机名、域名、网络服务器主页等。" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "常规配置" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "配置" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1247,47 +1240,47 @@ msgid "" "from various services" msgstr "日志记录了访问系统的人员,以及各种服务的调试信息" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "设置主机名错误:{exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "主机名设置" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "设置域名错误:{exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "域名集" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "设置主机名错误:{exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "网页服务器主页已设置" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "更改为高级模式时错误:{exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "展现先进的应用和特征" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "隐藏先进的应用和特征" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1297,7 +1290,7 @@ msgstr "" "Coturn是一个服务器,通过提供TURN和STUN协议的实现来促进音频/视频通话和会议。" "WebRTC、SIP和其他通信服务器可以使用它在无法相互连接的各方之间建立通话。" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse或" "ejabberd等服务器需要用这里提供的细节进行配置。" -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "网络电话助手" @@ -1364,26 +1357,26 @@ msgstr "设置时区错误:{exception}" msgid "Time zone set" msgstr "时区设置" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge 是一个有网页界面的 BitTorrent 客户端。" -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." msgstr "默认密码是“deluge”,但是你需要在启用此服务以后立刻登录并修改它。" -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "使用BitTorrent应用程序下载文件" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "启用 Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent 网页客户端" @@ -1508,7 +1501,7 @@ msgstr "结果" msgid "Diagnostic Test" msgstr "诊断测试" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1518,7 +1511,7 @@ msgstr "" "如果您的互联网提供商定期(例如每24小时)更改您的IP地址,其他人可能很难在互联" "网上找到您。这会阻止其他人找到由此 {box_name} 提供的服务。" -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1534,7 +1527,7 @@ msgstr "" "器会将您的 DNS 名称分配给新的 IP,如果互联网上的某人要求您的 DNS 名称,他们将" "从您当前 IP 地址收到响应。" -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1546,11 +1539,11 @@ msgstr "" "服务,或您可以在freedns.afraid.org 找到免费更新网址服务。" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "动态 DNS 客户端" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "动态域名" @@ -1671,7 +1664,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1726,7 +1719,7 @@ msgstr "服务器拒绝连接" msgid "Already up-to-date" msgstr "已是最新" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." @@ -1734,7 +1727,7 @@ msgstr "" "XMPP 是一种开放标准的通信协议。在这里你可以运行并配置您的 XMPP 服务器,称为 " "ejabberd。" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client。启用后,任何有 {box_name} 登录的用户均可访" "问 ejabberd。" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn应用程序或配置一个外部服务器。" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "ejabberd" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "聊天服务器" @@ -1870,14 +1863,14 @@ msgstr "" "%(domainname)s。你可以在系统的配置中设置你" "的域名。" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1885,7 +1878,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1895,13 +1888,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2026,7 +2019,7 @@ msgstr "端口" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2036,7 +2029,7 @@ msgstr "" "防火墙控制你的 {box_name} 上的进出网络流量。启用并正确配置防火墙上可以减少来" "自互联网的安全威胁。" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "防火墙" @@ -2056,52 +2049,39 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" -"防火墙守护程序未运行。请运行它。防火墙默认在 %(box_name)s 上启用。在任何基于 " -"Debian 的系统(例如 %(box_name)s)上,要运行它,您可以使用命令 “service " -"firewalld start” ,在使用 systemd 的系统上则使用 “systemctl start " -"firewalld”命令。" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "服务/端口" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "启用" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "已禁用" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "允许" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "允许(只允许内部连接)" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "允许(只允许外部连接)" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "已阻止" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " @@ -2110,13 +2090,13 @@ msgstr "" "防火墙的操作是自动的。当您启用服务时它也在防火墙中允许,当禁用一项服务时也会" "禁用防火墙中的相应服务。" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2162,7 +2142,7 @@ msgstr "启动安装程序" msgid "Setup Complete" msgstr "安装完成" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2173,73 +2153,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "无效的存储库 URL。" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "无效的存储库名称。" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "新存储库的名称或用于导入现有存储库的 URL。" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "存储库描述" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "储存库所有者名称" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "私有存储库" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "已存在同名存储库。" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "存储库名称" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "默认分支" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2283,19 +2263,19 @@ msgstr "删除 Git 存储库 %(name)s " msgid "Delete this repository permanently?" msgstr "永久删除此存储库?" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "已创建储存库。" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "创建存储库时发生错误。" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "已编辑储存库。" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "编辑存储库" @@ -2614,7 +2594,7 @@ msgstr "关于 {box_name}" msgid "{box_name} Manual" msgstr "{box_name} 手册" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2622,7 +2602,7 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." @@ -2630,25 +2610,25 @@ msgstr "" "I2P 项目的更多信息,请参阅 " "主页。" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "管理 I2P 应用程序" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "匿名网络" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "I2P 代理" @@ -2685,7 +2665,7 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " @@ -2694,7 +2674,7 @@ msgstr "" "ikiwiki是一个简单的 wiki 和博客应用程序。它支持几种轻量级标记语言,包括 " "Markdown 和常见的博客功能,如评论和 RSS 源。" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2703,15 +2683,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "ikiwiki" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "Wiki 和博客" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "查看和编辑 wiki 应用程序" @@ -2766,41 +2746,41 @@ msgid "" msgstr "" "此操作将删除所有文章、 网页和评论包括修订历史记录。 永久删除此 wiki 或博客吗?" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "创建 wiki {name}。" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "不能创建 wiki:{error}" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "已创建的博客 {name}。" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "不能创建博客:{error}" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "{title} 已被删除。" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "无法删除 {title}: {error}" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "infinoted 是一个 Gobby 服务器,Gobby 是一个协作化的文本编辑器。" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2810,11 +2790,11 @@ msgstr "" "要使用它, 下载 Gobby 的桌面客户端并" "安装。然后启动 Gobby 并选择“连接到服务器”并书入你的 {box_name} 域名即可。" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "Gobby 服务器" @@ -2860,7 +2840,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2878,7 +2858,7 @@ msgstr "" msgid "Chat Client" msgstr "聊天客户端" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2891,7 +2871,7 @@ msgstr "" "动获取和设置每个可用域名的数字证书。它通过向 Let's Encrypt 证明自己是一个域名" "的所有者。Let's Encrypt 是一个证书颁发机构(CA)。" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2902,15 +2882,15 @@ msgstr "" "(ISRG)为公众利益而设立。请在使用此服务之前阅读并同意 Let's Encypt 订阅者协议。" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "Let's Encrypt" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "证书" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2975,41 +2955,41 @@ msgstr "" "还没有配置域名。配置域名可以为它们获得相应的证" "书。" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "成功吊销了域名 {domain} 的证书。可能需要一会儿才能生效。" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "无法为 {domain} 撤销证书:{error}" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "为域名 {domain} 成功获得证书" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "未能为域名 {domain} 获取证书:{error}" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "成功删除域名 {domain} 的证书" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "删除 {domain} 域名证书失败:{error}" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -3019,14 +2999,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "Matrix Synapse" @@ -3109,7 +3089,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3117,7 +3097,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3126,18 +3106,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "共笔文档" @@ -3206,35 +3186,35 @@ msgstr "密码已更新" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "公开注册已启用" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "已禁用公开注册" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "已启用私密模式" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "已禁用私密模式" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "默认皮肤已更改" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 msgid "Domain name updated" msgstr "域名已更新" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 msgid "Site name updated" msgstr "站点名已更新" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3246,11 +3226,11 @@ msgstr "" "(30000)上运行 Minetest 服务器。要连接到服务器,需要 Minetest 客户端。" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "方块沙盒" @@ -3295,7 +3275,7 @@ msgstr "禁用后,玩家不能死或受到任何伤害。" msgid "Address" msgstr "地址" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3456,19 +3436,19 @@ msgstr "安全 Shell" msgid "Services" msgstr "服务" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "网络" @@ -3824,7 +3804,7 @@ msgstr "编辑连接" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "編輯" @@ -3929,7 +3909,7 @@ msgstr "IPv4" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "方法" @@ -3945,7 +3925,7 @@ msgstr "DNS 服务器" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "默认" @@ -3958,7 +3938,7 @@ msgid "This connection is not active." msgstr "此连接未处于激活状态。" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "安全" @@ -4498,7 +4478,7 @@ msgstr "连接 {name} 已删除。" msgid "Failed to delete connection: Connection not found." msgstr "删除连接失败: 找不到连接。" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4513,20 +4493,20 @@ msgstr "" "供的私人/内部服务。您还可以通过 {box_name} 访问互联网的其他部分,以增加安全性" "和匿名性。" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "连接到 VPN 服务" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "OpenVPN" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "虚拟专用网络" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4536,64 +4516,38 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "迁移" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "配置文件" -#: plinth/modules/openvpn/templates/openvpn.html:25 -#, python-format +#: plinth/modules/openvpn/templates/openvpn.html:15 +#, fuzzy, python-format +#| msgid "" +#| "To connect to %(box_name)s's VPN, you need to download a profile and feed " +#| "it to an OpenVPN client on your mobile or desktop machine. OpenVPN " +#| "Clients are available for most platforms. Click \"Learn more...\" above " +#| "for recommended clients and instructions on how to configure them." msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" "要连接到 %(box_name)s 的VPN,您需要下载配置文件并将其提供给移动或桌面计算机上" "的 OpenVPN 客户端。OpenVPN 客户端适用于大多数平台。要查看推荐的客户端及配置说" "明请点击上方的 “了解更多…”。" -#: plinth/modules/openvpn/templates/openvpn.html:35 -#, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +#: plinth/modules/openvpn/templates/openvpn.html:24 +#, fuzzy, python-format +#| msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "配置文件是特定于每个 %(box_name)s 用户的。请保持其私密。" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "下载我的配置文件" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4604,34 +4558,34 @@ msgstr "" "PageKite 是一种在您没有直接连接到互联网时暴露 {box_name} 服务的系统。 如果您" "的 {box_name} 服务无法从互联网访问,您只需要设置 PageKite。这包括以下情况:" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "{box_name} 位于受限的防火墙的后面。" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "{box_name} 已连接到非你控制的(无线)路由器。" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "您的 ISP 没有提供外部的 IP 地址而是通过提供 NAT 连接互联网。" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" "您的 ISP 不提供你一个静态的 IP 地址,每次连接到互联网时 IP 地址都会更改。" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "您的 ISP 限制传入的连接。" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4643,23 +4597,23 @@ msgstr "" "使用任何 pagekite 服务提供商,例如pagekite." "net。将来,您或许可以使用好友的 {box_name} 来使用此服务。" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "PageKite" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "公开可见性" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "PageKite 域名" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "服务器域" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." @@ -4667,65 +4621,65 @@ msgstr "" "选择您的 pagekite 服务器。设置\"pagekite.net\"以便使用默认的 pagekite.net 服" "务器。" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "服务器端口" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "你 pagekite 服务器的端口 (默认: 80)" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "Kite 名字" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "示例: mybox.pagekite.me" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "无效的 Kite 名称" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "Kite 密码" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "为 kite 设置的密码,如果没有为 kite 设置密码则会使用你账号的默认密码。" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "协议" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "外网(前端)端口" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "内网(freedombox)端口" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "启用子域" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "删除自定义服务" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "此服务已作为标准服务提供。" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "已添加的自定义服务" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "此服务已存在" @@ -4761,29 +4715,29 @@ msgstr "" "警告:
您的 PageKite 前端服务器可能不支持您在此处定义的所有协议/端" "口组合。例如,已知443以外的端口上的HTTPS会导致问题。" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "Web 服务器(HTTP)" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "网站可从 http://{0} 访问" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "Web 服务器(HTTPS)" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "网站可从 https://{0} 访问" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "安全 Shell(SSH)" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4827,8 +4781,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "重新启动" @@ -4871,6 +4825,39 @@ msgstr "" msgid "Shut Down Now" msgstr "现在关闭" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +#, fuzzy +#| msgid "Privoxy" +msgid "Privacy" +msgstr "Privoxy" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4908,7 +4895,7 @@ msgstr "Web 代理" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "在 tcp{kind} 上通过 {proxy} 访问 {url}" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4923,7 +4910,7 @@ msgstr "" "以运行 Quassel 核心服务,使您始终在线,并且可以使用桌面或移动设备上的一个或多" "个 Quassel 客户端连接和断开连接。" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your 桌面移动设备客户端连接到 Quassel 的核心。" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "IRC 客户端" @@ -4946,7 +4933,7 @@ msgstr "IRC 客户端" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4960,19 +4947,19 @@ msgstr "" "html#documentation/#idcaldav-and-carddavsupported-clients\">支持的客户端应用" "程序。任何拥有 {box_name} 登录名的用户都可以访问 Radicale。" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "日历和通讯录" @@ -5033,7 +5020,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "访问权配置已更新" @@ -5112,7 +5099,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5125,13 +5112,13 @@ msgstr "RSS-Bridge" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5140,31 +5127,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "网络文件存储" @@ -5242,15 +5229,15 @@ msgstr "共享名称" msgid "Action" msgstr "操作" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "FreedomBox 操作系统盘" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "打开共享" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "群组共享" @@ -5276,51 +5263,51 @@ msgstr "已禁用共享。" msgid "Error disabling share: {error_message}" msgstr "禁用共享出错:{error_message}" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "Web 搜索" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "安全搜索" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "中等" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5475,14 +5462,14 @@ msgstr "书签" msgid "Shaarlier" msgstr "Shaarlier" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5491,97 +5478,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "服务器" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "服务器端口" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "共享" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "公共分享" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "已存在同名共享。" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5618,19 +5605,19 @@ msgstr "已添加共享。" msgid "Add Share" msgstr "添加共享" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "已编辑共享。" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "编辑共享" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "已删除共享。" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " @@ -5639,7 +5626,7 @@ msgstr "" "快照可以允许创建并管理 btrfs 文件系统快照。这些可以用来回滚系统到前一个已知可" "用的状态,以防意外改变系统状态。" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5647,14 +5634,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "存储快照" @@ -5748,7 +5735,7 @@ msgstr "日期" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "删除快照" @@ -5798,57 +5785,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "回滚到快照 #%(number)s" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "已手动创建" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "管理快照" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "创建快照。" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "存储快照配置已更新" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "操作错误:{0} [{1}] [{2}]" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "已删除选定的快照" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "回滚到快照 #{number}。" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "系统需要重启以完成完全回滚。" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "回滚到快照" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5856,7 +5843,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "安全 Shell(SSH)服务器" @@ -5889,14 +5876,6 @@ msgstr "" msgid "Fingerprint" msgstr "指纹" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "启用密码的 SSH 身份验证。" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5909,7 +5888,7 @@ msgstr "登录" msgid "Logged out successfully." msgstr "已成功退出登录。" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5917,143 +5896,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "存储" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "{disk_size:.1f} 字节" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "{disk_size:.1f} KiB" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "{disk_size:.1f} MiB" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "{disk_size:.1f} GiB" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "{disk_size:.1f} TiB" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "已经在卸载设备。" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "已挂载此设备。" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "此设备未挂载。" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "无效的目录名。" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "路径不是一个目录。" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "目录" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "共享" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -6089,7 +6068,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "扩展根分区" @@ -6109,30 +6088,30 @@ msgstr "" "执行前请备份你的数据。这个操作以后,将会为你的根分区扩展出 " "%(expandable_root_size)s 空余空间。" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "扩展分区错误:{exception}" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "已成功扩展分区。" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6140,7 +6119,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6152,20 +6131,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "管理 Syncthing 程序" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6178,47 +6157,47 @@ msgstr "" "href=\"https://www.torproject.org/download/download-easy.html.en\">Tor浏览器" "。" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "你的 {box_name} 有一个 Tor SOCKS 端口在 TCP 端口 9050 上对内网可用。" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "Tor 洋葱服务" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "Tor 网桥中继" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "Tor 中继端口可用" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "已注册 Obfs3 传输" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "已注册 Obfs4 传输" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "在 tcp{kind} 上通过 Tor 访问 {url}" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "确认使用 Tor 通过 tcp{kind} 访问 {url}" @@ -6324,11 +6303,11 @@ msgstr "洋葱服务" msgid "Ports" msgstr "端口" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 msgid "Updating configuration" msgstr "更新配置" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, python-brace-format msgid "Error configuring app: {error}" msgstr "配置应用出错:{error}" @@ -6382,7 +6361,7 @@ msgstr "" msgid "Transmission" msgstr "Transmission" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " @@ -6391,7 +6370,7 @@ msgstr "" "Tiny Tiny RSS是一个新闻源(RSS / Atom)阅读器和聚合器,旨在允许从任何位置读取" "新闻,同时提供尽可能接近真实的桌面应用程序体验。" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, python-brace-format msgid "" "When enabled, Tiny Tiny RSS can be accessed by any " @@ -6400,17 +6379,17 @@ msgstr "" "启用后,属于该订阅源阅读器群的 任何用户均可访问 " "Tiny Tiny RSS。" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "新闻源阅读器" @@ -6418,12 +6397,12 @@ msgstr "新闻源阅读器" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "检查并应用最新软件和安全更新。" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6431,33 +6410,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "软件更新" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "FreedomBox 已更新" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "已启动分发更新" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6612,51 +6591,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "立即测试分发升级" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "配置无人参与升级时错误:{error}" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "已启用自动升级" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "已禁用自动升级" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "已启用分发升级" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "已禁用分发升级" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "升级过程开始。" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "开始升级失败。" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "启动分发升级测试。" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6664,15 +6643,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "用户和组" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "请检查 LDAP 条目“{search_item}”" @@ -6690,21 +6669,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "验证密码" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "密码无效。" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6716,12 +6695,12 @@ msgstr "" "单点登录的服务。

管理员(admin)组中的用户将能够登录所有服务。他们还可" "以通过 SSH 登录到系统并具有管理权限(sudo)。" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "创建 LDAP 用户失败:{error}" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "未能将新用户添加到 {group} 组:{error}" @@ -6739,41 +6718,41 @@ msgstr "" "设置 SSH 公钥将允许此用户安全地登录到系统不使用密码。您可以输入多个密钥,每行" "一个。将忽略空行和以 # 开头的行。" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "重命名 LDAP 用户失败。" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "无法从组中删除用户。" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "无法将用户添加到组。" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "不能设置 SSH 密钥。" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "更改用户状态失败。" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "更改 LDAP 用户密码失败。" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "未能将新用户添加到管理员组:{error}" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "限制控制台访问失败:{error}" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "用户帐户已创建,您现在可以登录" @@ -6790,12 +6769,12 @@ msgstr "保存密码" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "创建用户" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "删除用户" @@ -6835,17 +6814,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "用户" @@ -6876,34 +6855,34 @@ msgstr "使用 更改密码表单 更改 msgid "Save Changes" msgstr "保存更改" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "用户 %(username)s 已创建。" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "用户 %(username)s 已更新。" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "编辑用户" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "用户 {user} 已删除。" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "删除 LDAP 用户失败。" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "更改密码" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "已成功更改密码。" @@ -7212,7 +7191,7 @@ msgstr "删除与服务器的连接" msgid "Server deleted." msgstr "服务器已删除。" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7221,7 +7200,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7230,26 +7209,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "WordPress" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "网站和博客" @@ -7263,7 +7242,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7276,7 +7255,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7284,11 +7263,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7337,96 +7316,92 @@ msgstr "" msgid "Finished: {name}" msgstr "已完成:{name}" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -msgid "Error running apt-get" -msgstr "运行 apt-get 出错" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "安装" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "下载中" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "媒体改变" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "配置文件:{file}" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "安装应用中" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, python-brace-format msgid "Error installing app: {string} {details}" msgstr "安装应用出错:{string} {details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, python-brace-format msgid "Error updating app: {string} {details}" msgstr "更新应用出错:{string} {details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, python-brace-format msgid "Error installing app: {error}" msgstr "安装应用出错:{error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, python-brace-format msgid "Error updating app: {error}" msgstr "更新应用出错:{error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 msgid "App installed." msgstr "应用已安装。" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "应用已更新" -#: plinth/setup.py:104 +#: plinth/setup.py:105 msgid "Uninstalling app" msgstr "卸载应用" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, python-brace-format msgid "Error uninstalling app: {string} {details}" msgstr "卸载应用出错:{string} {details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, python-brace-format msgid "Error uninstalling app: {error}" msgstr "卸载应用出错:{error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 msgid "App uninstalled." msgstr "应用已卸载。" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "更新软件包中" @@ -7484,53 +7459,54 @@ msgstr "安装" msgid "Service %(service_name)s is not running." msgstr "服务 %(service_name)s 未在运行。" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "%(box_name)s 的核心功能和网络界面" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." +msgstr "" -#: plinth/templates/base.html:107 +#: plinth/templates/base.html:110 msgid " Home" msgstr " 主页" -#: plinth/templates/base.html:110 +#: plinth/templates/base.html:113 msgid "Home" msgstr "主页" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr " 应用程序" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "应用程序" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr " 系统" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "系统" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "更改密码" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "关闭" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "登出" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "选择语言" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "登录" @@ -7797,6 +7773,37 @@ msgstr "" msgid "Gujarati" msgstr "古吉拉特语" +#~ msgid "Enable DNSSEC" +#~ msgstr "启用 DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "启用域名系统安全扩展(DNSSEC)" + +#, python-format +#~ msgid "" +#~ "Firewall daemon is not running. Please run it. Firewall comes enabled by " +#~ "default on %(box_name)s. On any Debian based system (such as " +#~ "%(box_name)s) you may run it using the command 'service firewalld start' " +#~ "or in case of a system with systemd 'systemctl start firewalld'." +#~ msgstr "" +#~ "防火墙守护程序未运行。请运行它。防火墙默认在 %(box_name)s 上启用。在任何基" +#~ "于 Debian 的系统(例如 %(box_name)s)上,要运行它,您可以使用命令 " +#~ "“service firewalld start” ,在使用 systemd 的系统上则使用 “systemctl " +#~ "start firewalld”命令。" + +#~ msgid "Migrate" +#~ msgstr "迁移" + +#~ msgid "SSH authentication with password enabled." +#~ msgstr "启用密码的 SSH 身份验证。" + +#~ msgid "Error running apt-get" +#~ msgstr "运行 apt-get 出错" + +#, python-format +#~ msgid "Core functionality and web interface for %(box_name)s" +#~ msgstr "%(box_name)s 的核心功能和网络界面" + #~ msgid "Network Connections" #~ msgstr "网络连接" diff --git a/plinth/locale/zh_Hant/LC_MESSAGES/django.po b/plinth/locale/zh_Hant/LC_MESSAGES/django.po index e3dab660a..2581b4a9c 100644 --- a/plinth/locale/zh_Hant/LC_MESSAGES/django.po +++ b/plinth/locale/zh_Hant/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-26 19:51-0400\n" +"POT-Creation-Date: 2022-10-10 21:35-0400\n" "PO-Revision-Date: 2021-12-23 12:50+0000\n" "Last-Translator: pesder \n" "Language-Team: Chinese (Traditional) calibre group will be able to access the " "app. All users with access can use all the libraries." @@ -1008,29 +1001,29 @@ msgstr "" "只有屬於 calibre 群組的使用者可以存取這個 app。每個能存取的使用者都" "可以使用所有的圖書館。" -#: plinth/modules/calibre/__init__.py:55 +#: plinth/modules/calibre/__init__.py:51 msgid "Use calibre e-book libraries" msgstr "使用 calibre 電子書庫" -#: plinth/modules/calibre/__init__.py:58 plinth/modules/calibre/manifest.py:6 +#: plinth/modules/calibre/__init__.py:54 plinth/modules/calibre/manifest.py:6 msgid "calibre" msgstr "calibre" -#: plinth/modules/calibre/__init__.py:59 +#: plinth/modules/calibre/__init__.py:55 msgid "E-book Library" msgstr "電子書圖書館" -#: plinth/modules/calibre/forms.py:18 +#: plinth/modules/calibre/forms.py:16 msgid "Name of the new library" msgstr "新圖書館名稱" -#: plinth/modules/calibre/forms.py:19 +#: plinth/modules/calibre/forms.py:17 msgid "" "Only letters of the English alphabet, numbers and the characters _ . and - " "without spaces or special characters. Example: My_Library_2000" msgstr "" -#: plinth/modules/calibre/forms.py:30 +#: plinth/modules/calibre/forms.py:28 msgid "A library with this name already exists." msgstr "已存在同樣名稱的圖書館。" @@ -1076,20 +1069,20 @@ msgstr "前往至圖書館 %(library)s" msgid "Delete library %(library)s" msgstr "刪除圖書館 %(library)s" -#: plinth/modules/calibre/views.py:41 +#: plinth/modules/calibre/views.py:39 msgid "Library created." msgstr "圖書已建立。" -#: plinth/modules/calibre/views.py:52 +#: plinth/modules/calibre/views.py:49 msgid "An error occurred while creating the library." msgstr "建立圖書館時發生錯誤。" -#: plinth/modules/calibre/views.py:66 plinth/modules/gitweb/views.py:143 +#: plinth/modules/calibre/views.py:63 plinth/modules/gitweb/views.py:139 #, python-brace-format msgid "{name} deleted." msgstr "{name} 已刪除。" -#: plinth/modules/calibre/views.py:70 plinth/modules/gitweb/views.py:147 +#: plinth/modules/calibre/views.py:67 plinth/modules/gitweb/views.py:143 #, python-brace-format msgid "Could not delete {name}: {error}" msgstr "無法刪除 {name}: {error}" @@ -1134,7 +1127,7 @@ msgstr "Cockpit" msgid "Server Administration" msgstr "伺服器管理" -#: plinth/modules/config/__init__.py:25 +#: plinth/modules/config/__init__.py:22 msgid "" "Here you can set some general configuration options like hostname, domain " "name, webserver home page etc." @@ -1142,18 +1135,18 @@ msgstr "" "在這裡您可以設定某些一般設定選項,像是主機名稱、網域名稱、網頁伺服器首頁等" "等。" -#: plinth/modules/config/__init__.py:53 +#: plinth/modules/config/__init__.py:44 msgid "General Configuration" msgstr "一般配置" -#: plinth/modules/config/__init__.py:58 +#: plinth/modules/config/__init__.py:49 #: plinth/modules/names/templates/names.html:30 #: plinth/modules/names/templates/names.html:44 -#: plinth/modules/snapshot/views.py:37 plinth/templates/index.html:38 +#: plinth/modules/snapshot/views.py:32 plinth/templates/index.html:38 msgid "Configure" msgstr "配置" -#: plinth/modules/config/__init__.py:71 plinth/modules/config/forms.py:68 +#: plinth/modules/config/__init__.py:62 plinth/modules/config/forms.py:68 #: plinth/modules/dynamicdns/forms.py:82 #: plinth/modules/names/templates/names.html:16 msgid "Domain Name" @@ -1259,47 +1252,47 @@ msgid "" "from various services" msgstr "" -#: plinth/modules/config/views.py:50 +#: plinth/modules/config/views.py:49 #, python-brace-format msgid "Error setting hostname: {exception}" msgstr "設定主機名稱時發生錯誤︰{exception}" -#: plinth/modules/config/views.py:53 +#: plinth/modules/config/views.py:52 msgid "Hostname set" msgstr "主機名稱設定" -#: plinth/modules/config/views.py:62 +#: plinth/modules/config/views.py:61 #, python-brace-format msgid "Error setting domain name: {exception}" msgstr "設定網域名稱時發生錯誤︰{exception}" -#: plinth/modules/config/views.py:65 +#: plinth/modules/config/views.py:64 msgid "Domain name set" msgstr "網域名稱設定" -#: plinth/modules/config/views.py:73 +#: plinth/modules/config/views.py:72 #, python-brace-format msgid "Error setting webserver home page: {exception}" msgstr "設定網頁伺服器首頁時發生錯誤︰{exception}" -#: plinth/modules/config/views.py:76 +#: plinth/modules/config/views.py:75 msgid "Webserver home page set" msgstr "網頁伺服器首頁設定" -#: plinth/modules/config/views.py:84 +#: plinth/modules/config/views.py:83 #, python-brace-format msgid "Error changing advanced mode: {exception}" msgstr "改變進階模式時發生錯誤︰{exception}" -#: plinth/modules/config/views.py:89 +#: plinth/modules/config/views.py:88 msgid "Showing advanced apps and features" msgstr "顯示進階 app 與功能" -#: plinth/modules/config/views.py:92 +#: plinth/modules/config/views.py:91 msgid "Hiding advanced apps and features" msgstr "隱藏進階 app 與功能" -#: plinth/modules/coturn/__init__.py:29 +#: plinth/modules/coturn/__init__.py:25 msgid "" "Coturn is a server to facilitate audio/video calls and conferences by " "providing an implementation of TURN and STUN protocols. WebRTC, SIP and " @@ -1310,7 +1303,7 @@ msgstr "" "和會議。 WebRTC、SIP 和其他通訊伺服器可以使用它在無法相互連接的各方之間建立通" "訊。" -#: plinth/modules/coturn/__init__.py:34 +#: plinth/modules/coturn/__init__.py:30 #, python-brace-format msgid "" "It is not meant to be used directly by users. Servers such as Matrix Synapse " "或 ejabberd 都需要以在這裡提供的資料來設定。" -#: plinth/modules/coturn/__init__.py:56 +#: plinth/modules/coturn/__init__.py:52 msgid "Coturn" msgstr "Coturn" -#: plinth/modules/coturn/__init__.py:57 +#: plinth/modules/coturn/__init__.py:53 msgid "VoIP Helper" msgstr "VoIP 協助程式" @@ -1377,26 +1370,26 @@ msgstr "設定時區時發生錯誤︰{exception}" msgid "Time zone set" msgstr "時區設定" -#: plinth/modules/deluge/__init__.py:22 +#: plinth/modules/deluge/__init__.py:19 msgid "Deluge is a BitTorrent client that features a Web UI." msgstr "Deluge 是一個具有網頁使用者介面的 BitTorrent 客戶端。" -#: plinth/modules/deluge/__init__.py:23 +#: plinth/modules/deluge/__init__.py:20 msgid "" "The default password is 'deluge', but you should log in and change it " "immediately after enabling this service." msgstr "預設的密碼是「deluge」,但啟用這個服務後您應該登入並立即改變它。" -#: plinth/modules/deluge/__init__.py:42 +#: plinth/modules/deluge/__init__.py:39 #: plinth/modules/transmission/__init__.py:62 msgid "Download files using BitTorrent applications" msgstr "使用 BitTorrent 應用程式下載檔案" -#: plinth/modules/deluge/__init__.py:46 plinth/modules/deluge/manifest.py:6 +#: plinth/modules/deluge/__init__.py:43 plinth/modules/deluge/manifest.py:6 msgid "Deluge" msgstr "Deluge" -#: plinth/modules/deluge/__init__.py:48 +#: plinth/modules/deluge/__init__.py:45 #: plinth/modules/transmission/__init__.py:68 msgid "BitTorrent Web Client" msgstr "BitTorrent 網頁客戶端" @@ -1515,7 +1508,7 @@ msgstr "" msgid "Diagnostic Test" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:29 +#: plinth/modules/dynamicdns/__init__.py:28 #, python-brace-format msgid "" "If your Internet provider changes your IP address periodically (i.e. every " @@ -1523,7 +1516,7 @@ msgid "" "prevent others from finding services which are provided by this {box_name}." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:33 +#: plinth/modules/dynamicdns/__init__.py:32 msgid "" "The solution is to assign a DNS name to your IP address and update the DNS " "name every time your IP is changed by your Internet provider. Dynamic DNS " @@ -1534,7 +1527,7 @@ msgid "" "IP address." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:41 +#: plinth/modules/dynamicdns/__init__.py:40 msgid "" "If you are looking for a free dynamic DNS account, you may find a free " "GnuDIP service at ddns." @@ -1542,11 +1535,11 @@ msgid "" "href='http://freedns.afraid.org/' target='_blank'>freedns.afraid.org." msgstr "" -#: plinth/modules/dynamicdns/__init__.py:62 +#: plinth/modules/dynamicdns/__init__.py:61 msgid "Dynamic DNS Client" msgstr "" -#: plinth/modules/dynamicdns/__init__.py:75 +#: plinth/modules/dynamicdns/__init__.py:74 msgid "Dynamic Domain Name" msgstr "" @@ -1658,7 +1651,7 @@ msgstr "" #: plinth/modules/dynamicdns/templates/dynamicdns.html:11 #: plinth/modules/ejabberd/templates/ejabberd.html:13 #: plinth/modules/firewall/templates/firewall.html:16 -#: plinth/modules/firewall/templates/firewall.html:36 +#: plinth/modules/firewall/templates/firewall.html:22 #: plinth/modules/letsencrypt/templates/letsencrypt.html:17 #: plinth/modules/matrixsynapse/templates/matrix-synapse.html:12 #: plinth/modules/networks/templates/connection_show.html:254 @@ -1721,13 +1714,13 @@ msgstr "" msgid "Already up-to-date" msgstr "" -#: plinth/modules/ejabberd/__init__.py:31 +#: plinth/modules/ejabberd/__init__.py:29 msgid "" "XMPP is an open and standardized communication protocol. Here you can run " "and configure your XMPP server, called ejabberd." msgstr "" -#: plinth/modules/ejabberd/__init__.py:34 +#: plinth/modules/ejabberd/__init__.py:32 #, python-brace-format msgid "" "To actually communicate, you can use the web client user with a {box_name} login." msgstr "" -#: plinth/modules/ejabberd/__init__.py:42 +#: plinth/modules/ejabberd/__init__.py:40 #, python-brace-format msgid "" "ejabberd needs a STUN/TURN server for audio/video calls. Install the Coturn app or configure an external server." msgstr "" -#: plinth/modules/ejabberd/__init__.py:63 +#: plinth/modules/ejabberd/__init__.py:61 msgid "ejabberd" msgstr "" -#: plinth/modules/ejabberd/__init__.py:64 -#: plinth/modules/matrixsynapse/__init__.py:69 +#: plinth/modules/ejabberd/__init__.py:62 +#: plinth/modules/matrixsynapse/__init__.py:56 msgid "Chat Server" msgstr "" @@ -1851,14 +1844,14 @@ msgid "" "Configure page." msgstr "" -#: plinth/modules/email/__init__.py:26 +#: plinth/modules/email/__init__.py:25 msgid "" "This is a complete email server solution using Postfix, Dovecot, and Rspamd. " "Postfix sends and receives emails. Dovecot allows email clients to access " "your mailbox using IMAP and POP3. Rspamd deals with spam." msgstr "" -#: plinth/modules/email/__init__.py:30 +#: plinth/modules/email/__init__.py:29 msgid "" "Email server currently does not work with many free domain services " "including those provided by the FreedomBox Foundation. Many ISPs also " @@ -1866,7 +1859,7 @@ msgid "" "request. See manual page for more information." msgstr "" -#: plinth/modules/email/__init__.py:35 +#: plinth/modules/email/__init__.py:34 #, python-brace-format msgid "" "Each user on {box_name} gets an email address like user@mydomain.example. " @@ -1876,13 +1869,13 @@ msgid "" "to the first admin user." msgstr "" -#: plinth/modules/email/__init__.py:41 +#: plinth/modules/email/__init__.py:40 msgid "" "Roundcube app provides web interface " "for users to access email." msgstr "" -#: plinth/modules/email/__init__.py:43 +#: plinth/modules/email/__init__.py:42 msgid "" "During installation, any other email servers in the system will be " "uninstalled." @@ -2021,7 +2014,7 @@ msgstr "" msgid "Host/Target/Value" msgstr "" -#: plinth/modules/firewall/__init__.py:26 +#: plinth/modules/firewall/__init__.py:23 #, python-brace-format msgid "" "Firewall is a security system that controls the incoming and outgoing " @@ -2029,7 +2022,7 @@ msgid "" "configured reduces risk of security threat from the Internet." msgstr "" -#: plinth/modules/firewall/__init__.py:60 +#: plinth/modules/firewall/__init__.py:57 msgid "Firewall" msgstr "" @@ -2049,61 +2042,52 @@ msgid "Port {name} ({details}) unavailable for external networks" msgstr "" #: plinth/modules/firewall/templates/firewall.html:21 -#, python-format -msgid "" -"Firewall daemon is not running. Please run it. Firewall comes enabled by " -"default on %(box_name)s. On any Debian based system (such as %(box_name)s) " -"you may run it using the command 'service firewalld start' or in case of a " -"system with systemd 'systemctl start firewalld'." -msgstr "" - -#: plinth/modules/firewall/templates/firewall.html:35 msgid "Service/Port" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:54 +#: plinth/modules/firewall/templates/firewall.html:40 #: plinth/modules/letsencrypt/templates/letsencrypt.html:69 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 msgid "Enabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:57 +#: plinth/modules/firewall/templates/firewall.html:43 #: plinth/modules/letsencrypt/templates/letsencrypt.html:71 #: plinth/modules/snapshot/forms.py:23 plinth/modules/snapshot/forms.py:29 #: plinth/templates/cards.html:34 msgid "Disabled" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:72 +#: plinth/modules/firewall/templates/firewall.html:58 msgid "Permitted" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:75 +#: plinth/modules/firewall/templates/firewall.html:61 msgid "Permitted (internal only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:78 +#: plinth/modules/firewall/templates/firewall.html:64 msgid "Permitted (external only)" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:81 +#: plinth/modules/firewall/templates/firewall.html:67 msgid "Blocked" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:94 +#: plinth/modules/firewall/templates/firewall.html:80 msgid "" "The operation of the firewall is automatic. When you enable a service it is " "also permitted in the firewall and when you disable a service it is also " "disabled in the firewall." msgstr "" -#: plinth/modules/firewall/templates/firewall.html:102 +#: plinth/modules/firewall/templates/firewall.html:88 #: plinth/modules/networks/templates/networks_configuration.html:22 #: plinth/modules/storage/templates/storage.html:93 msgid "Advanced" msgstr "" -#: plinth/modules/firewall/templates/firewall.html:104 +#: plinth/modules/firewall/templates/firewall.html:90 msgid "" "Advanced firewall operations such as opening custom ports are provided by " "the Cockpit app." @@ -2149,7 +2133,7 @@ msgstr "" msgid "Setup Complete" msgstr "" -#: plinth/modules/gitweb/__init__.py:26 +#: plinth/modules/gitweb/__init__.py:21 msgid "" "Git is a distributed version-control system for tracking changes in source " "code during software development. Gitweb provides a web interface to Git " @@ -2160,73 +2144,73 @@ msgid "" "the world." msgstr "" -#: plinth/modules/gitweb/__init__.py:33 +#: plinth/modules/gitweb/__init__.py:28 msgid "" "To learn more on how to use Git visit Git tutorial." msgstr "" -#: plinth/modules/gitweb/__init__.py:49 +#: plinth/modules/gitweb/__init__.py:44 msgid "Read-write access to Git repositories" msgstr "" -#: plinth/modules/gitweb/__init__.py:54 plinth/modules/gitweb/manifest.py:10 +#: plinth/modules/gitweb/__init__.py:49 plinth/modules/gitweb/manifest.py:10 msgid "Gitweb" msgstr "" -#: plinth/modules/gitweb/__init__.py:55 +#: plinth/modules/gitweb/__init__.py:50 msgid "Simple Git Hosting" msgstr "" -#: plinth/modules/gitweb/forms.py:59 +#: plinth/modules/gitweb/forms.py:58 msgid "Invalid repository URL." msgstr "" -#: plinth/modules/gitweb/forms.py:69 +#: plinth/modules/gitweb/forms.py:68 msgid "Invalid repository name." msgstr "" -#: plinth/modules/gitweb/forms.py:77 +#: plinth/modules/gitweb/forms.py:76 msgid "Name of a new repository or URL to import an existing repository." msgstr "" -#: plinth/modules/gitweb/forms.py:83 +#: plinth/modules/gitweb/forms.py:82 msgid "Description of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:84 plinth/modules/gitweb/forms.py:88 +#: plinth/modules/gitweb/forms.py:83 plinth/modules/gitweb/forms.py:87 msgid "Optional, for displaying on Gitweb." msgstr "" -#: plinth/modules/gitweb/forms.py:86 +#: plinth/modules/gitweb/forms.py:85 msgid "Repository's owner name" msgstr "" -#: plinth/modules/gitweb/forms.py:91 +#: plinth/modules/gitweb/forms.py:90 msgid "Private repository" msgstr "" -#: plinth/modules/gitweb/forms.py:92 +#: plinth/modules/gitweb/forms.py:91 msgid "Allow only authorized users to access this repository." msgstr "" -#: plinth/modules/gitweb/forms.py:113 plinth/modules/gitweb/forms.py:155 +#: plinth/modules/gitweb/forms.py:112 plinth/modules/gitweb/forms.py:154 msgid "A repository with this name already exists." msgstr "" -#: plinth/modules/gitweb/forms.py:126 +#: plinth/modules/gitweb/forms.py:125 msgid "Name of the repository" msgstr "" -#: plinth/modules/gitweb/forms.py:130 +#: plinth/modules/gitweb/forms.py:129 msgid "An alpha-numeric string that uniquely identifies a repository." msgstr "" -#: plinth/modules/gitweb/forms.py:134 +#: plinth/modules/gitweb/forms.py:133 msgid "Default branch" msgstr "" -#: plinth/modules/gitweb/forms.py:135 +#: plinth/modules/gitweb/forms.py:134 msgid "Gitweb displays this as a default branch." msgstr "" @@ -2270,19 +2254,19 @@ msgstr "" msgid "Delete this repository permanently?" msgstr "" -#: plinth/modules/gitweb/views.py:49 +#: plinth/modules/gitweb/views.py:46 msgid "Repository created." msgstr "" -#: plinth/modules/gitweb/views.py:73 +#: plinth/modules/gitweb/views.py:69 msgid "An error occurred while creating the repository." msgstr "" -#: plinth/modules/gitweb/views.py:88 +#: plinth/modules/gitweb/views.py:84 msgid "Repository edited." msgstr "" -#: plinth/modules/gitweb/views.py:93 +#: plinth/modules/gitweb/views.py:89 msgid "Edit repository" msgstr "" @@ -2575,7 +2559,7 @@ msgstr "" msgid "{box_name} Manual" msgstr "" -#: plinth/modules/i2p/__init__.py:22 +#: plinth/modules/i2p/__init__.py:19 msgid "" "The Invisible Internet Project is an anonymous network layer intended to " "protect communication from censorship and surveillance. I2P provides " @@ -2583,31 +2567,31 @@ msgid "" "distributed around the world." msgstr "" -#: plinth/modules/i2p/__init__.py:26 +#: plinth/modules/i2p/__init__.py:23 msgid "" "Find more information about I2P on their project homepage." msgstr "" -#: plinth/modules/i2p/__init__.py:28 +#: plinth/modules/i2p/__init__.py:25 msgid "" "The first visit to the provided web interface will initiate the " "configuration process." msgstr "" -#: plinth/modules/i2p/__init__.py:50 +#: plinth/modules/i2p/__init__.py:47 msgid "Manage I2P application" msgstr "" -#: plinth/modules/i2p/__init__.py:53 plinth/modules/i2p/manifest.py:13 +#: plinth/modules/i2p/__init__.py:50 plinth/modules/i2p/manifest.py:13 msgid "I2P" msgstr "" -#: plinth/modules/i2p/__init__.py:54 plinth/modules/tor/__init__.py:53 +#: plinth/modules/i2p/__init__.py:51 plinth/modules/tor/__init__.py:49 msgid "Anonymity Network" msgstr "" -#: plinth/modules/i2p/__init__.py:80 +#: plinth/modules/i2p/__init__.py:77 msgid "I2P Proxy" msgstr "" @@ -2644,14 +2628,14 @@ msgid "" "a file." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:22 +#: plinth/modules/ikiwiki/__init__.py:19 msgid "" "ikiwiki is a simple wiki and blog application. It supports several " "lightweight markup languages, including Markdown, and common blogging " "functionality such as comments and RSS feeds." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:26 +#: plinth/modules/ikiwiki/__init__.py:23 #, python-brace-format msgid "" "Only {box_name} users in the admin group can create and " @@ -2660,15 +2644,15 @@ msgid "" "Configuration you can change these permissions or add new users." msgstr "" -#: plinth/modules/ikiwiki/__init__.py:47 plinth/modules/ikiwiki/manifest.py:6 +#: plinth/modules/ikiwiki/__init__.py:44 plinth/modules/ikiwiki/manifest.py:6 msgid "ikiwiki" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:48 +#: plinth/modules/ikiwiki/__init__.py:45 msgid "Wiki and Blog" msgstr "" -#: plinth/modules/ikiwiki/__init__.py:75 +#: plinth/modules/ikiwiki/__init__.py:72 msgid "View and edit wiki applications" msgstr "" @@ -2722,41 +2706,41 @@ msgid "" "history. Delete this wiki or blog permanently?" msgstr "" -#: plinth/modules/ikiwiki/views.py:74 +#: plinth/modules/ikiwiki/views.py:69 #, python-brace-format msgid "Created wiki {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:77 +#: plinth/modules/ikiwiki/views.py:72 #, python-brace-format msgid "Could not create wiki: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:87 +#: plinth/modules/ikiwiki/views.py:79 #, python-brace-format msgid "Created blog {name}." msgstr "" -#: plinth/modules/ikiwiki/views.py:90 +#: plinth/modules/ikiwiki/views.py:82 #, python-brace-format msgid "Could not create blog: {error}" msgstr "" -#: plinth/modules/ikiwiki/views.py:106 +#: plinth/modules/ikiwiki/views.py:98 #, python-brace-format msgid "{title} deleted." msgstr "" -#: plinth/modules/ikiwiki/views.py:110 +#: plinth/modules/ikiwiki/views.py:102 #, python-brace-format msgid "Could not delete {title}: {error}" msgstr "" -#: plinth/modules/infinoted/__init__.py:21 +#: plinth/modules/infinoted/__init__.py:20 msgid "infinoted is a server for Gobby, a collaborative text editor." msgstr "" -#: plinth/modules/infinoted/__init__.py:23 +#: plinth/modules/infinoted/__init__.py:22 #, python-brace-format msgid "" "To use it, download Gobby, desktop " @@ -2764,11 +2748,11 @@ msgid "" "enter your {box_name}'s domain name." msgstr "" -#: plinth/modules/infinoted/__init__.py:42 +#: plinth/modules/infinoted/__init__.py:41 msgid "infinoted" msgstr "" -#: plinth/modules/infinoted/__init__.py:43 +#: plinth/modules/infinoted/__init__.py:42 msgid "Gobby Server" msgstr "" @@ -2814,7 +2798,7 @@ msgstr "" #: plinth/modules/janus/templates/janus_video_room.html:205 #: plinth/modules/jsxc/templates/jsxc_launch.html:117 -#: plinth/templates/base.html:247 +#: plinth/templates/base.html:250 msgid "JavaScript license information" msgstr "" @@ -2832,7 +2816,7 @@ msgstr "" msgid "Chat Client" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:28 +#: plinth/modules/letsencrypt/__init__.py:24 #, python-brace-format msgid "" "A digital certificate allows users of a web service to verify the identity " @@ -2842,7 +2826,7 @@ msgid "" "Encrypt, a certificate authority (CA)." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:34 +#: plinth/modules/letsencrypt/__init__.py:30 msgid "" "Let's Encrypt is a free, automated, and open certificate authority, run for " "the public's benefit by the Internet Security Research Group (ISRG). Please " @@ -2850,15 +2834,15 @@ msgid "" "\">Let's Encrypt Subscriber Agreement before using this service." msgstr "" -#: plinth/modules/letsencrypt/__init__.py:61 +#: plinth/modules/letsencrypt/__init__.py:57 msgid "Let's Encrypt" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:62 +#: plinth/modules/letsencrypt/__init__.py:58 msgid "Certificates" msgstr "" -#: plinth/modules/letsencrypt/__init__.py:98 +#: plinth/modules/letsencrypt/__init__.py:94 msgid "Cannot test: No domains are configured." msgstr "" @@ -2921,41 +2905,41 @@ msgid "" "domains to be able to obtain certificates for them." msgstr "" -#: plinth/modules/letsencrypt/views.py:41 +#: plinth/modules/letsencrypt/views.py:40 #, python-brace-format msgid "" "Certificate successfully revoked for domain {domain}.This may take a few " "moments to take effect." msgstr "" -#: plinth/modules/letsencrypt/views.py:47 +#: plinth/modules/letsencrypt/views.py:46 #, python-brace-format msgid "Failed to revoke certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:60 -#: plinth/modules/letsencrypt/views.py:77 +#: plinth/modules/letsencrypt/views.py:59 +#: plinth/modules/letsencrypt/views.py:76 #, python-brace-format msgid "Certificate successfully obtained for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:65 -#: plinth/modules/letsencrypt/views.py:82 +#: plinth/modules/letsencrypt/views.py:64 +#: plinth/modules/letsencrypt/views.py:81 #, python-brace-format msgid "Failed to obtain certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/letsencrypt/views.py:94 +#: plinth/modules/letsencrypt/views.py:93 #, python-brace-format msgid "Certificate successfully deleted for domain {domain}" msgstr "" -#: plinth/modules/letsencrypt/views.py:99 +#: plinth/modules/letsencrypt/views.py:98 #, python-brace-format msgid "Failed to delete certificate for domain {domain}: {error}" msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:29 +#: plinth/modules/matrixsynapse/__init__.py:26 msgid "" "Matrix is an new " "ecosystem for open, federated instant messaging and VoIP. Synapse is a " @@ -2965,14 +2949,14 @@ msgid "" "converse with users on all other Matrix servers via federation." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:37 +#: plinth/modules/matrixsynapse/__init__.py:34 #, python-brace-format msgid "" "Matrix Synapse needs a STUN/TURN server for audio/video calls. Install the " "Coturn app or configure an external server." msgstr "" -#: plinth/modules/matrixsynapse/__init__.py:68 +#: plinth/modules/matrixsynapse/__init__.py:55 msgid "Matrix Synapse" msgstr "" @@ -3053,7 +3037,7 @@ msgid "" "go to Let's Encrypt to obtain one." msgstr "" -#: plinth/modules/mediawiki/__init__.py:23 +#: plinth/modules/mediawiki/__init__.py:20 msgid "" "MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia " "projects. A wiki engine is a program for creating a collaboratively edited " @@ -3061,7 +3045,7 @@ msgid "" "collaborate with friends on projects." msgstr "" -#: plinth/modules/mediawiki/__init__.py:27 +#: plinth/modules/mediawiki/__init__.py:24 msgid "" "This MediaWiki instance comes with a randomly generated administrator " "password. You can set a new password in the \"Configuration\" section and " @@ -3070,18 +3054,18 @@ msgid "" "CreateAccount\">Special:CreateAccount page." msgstr "" -#: plinth/modules/mediawiki/__init__.py:33 +#: plinth/modules/mediawiki/__init__.py:30 msgid "" "Anyone with a link to this wiki can read it. Only users that are logged in " "can make changes to the content." msgstr "" -#: plinth/modules/mediawiki/__init__.py:54 +#: plinth/modules/mediawiki/__init__.py:51 #: plinth/modules/mediawiki/manifest.py:6 msgid "MediaWiki" msgstr "" -#: plinth/modules/mediawiki/__init__.py:55 plinth/templates/index.html:124 +#: plinth/modules/mediawiki/__init__.py:52 plinth/templates/index.html:124 msgid "Wiki" msgstr "" @@ -3152,39 +3136,39 @@ msgstr "" msgid "Password update failed. Please choose a stronger password" msgstr "" -#: plinth/modules/mediawiki/views.py:69 +#: plinth/modules/mediawiki/views.py:68 msgid "Public registrations enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:78 +#: plinth/modules/mediawiki/views.py:76 msgid "Public registrations disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:83 +#: plinth/modules/mediawiki/views.py:81 msgid "Private mode enabled" msgstr "" -#: plinth/modules/mediawiki/views.py:90 +#: plinth/modules/mediawiki/views.py:87 msgid "Private mode disabled" msgstr "" -#: plinth/modules/mediawiki/views.py:98 +#: plinth/modules/mediawiki/views.py:95 msgid "Default skin changed" msgstr "" -#: plinth/modules/mediawiki/views.py:102 +#: plinth/modules/mediawiki/views.py:99 #, fuzzy #| msgid "Domain name set" msgid "Domain name updated" msgstr "網域名稱設定" -#: plinth/modules/mediawiki/views.py:106 +#: plinth/modules/mediawiki/views.py:103 #, fuzzy #| msgid "Domain name set" msgid "Site name updated" msgstr "網域名稱設定" -#: plinth/modules/minetest/__init__.py:35 +#: plinth/modules/minetest/__init__.py:33 #, python-brace-format msgid "" "Minetest is a multiplayer infinite-world block sandbox. This module enables " @@ -3193,11 +3177,11 @@ msgid "" "downloads/\">Minetest client is needed." msgstr "" -#: plinth/modules/minetest/__init__.py:58 plinth/modules/minetest/manifest.py:9 +#: plinth/modules/minetest/__init__.py:56 plinth/modules/minetest/manifest.py:9 msgid "Minetest" msgstr "" -#: plinth/modules/minetest/__init__.py:59 +#: plinth/modules/minetest/__init__.py:57 msgid "Block Sandbox" msgstr "" @@ -3242,7 +3226,7 @@ msgstr "" msgid "Address" msgstr "" -#: plinth/modules/minidlna/__init__.py:21 +#: plinth/modules/minidlna/__init__.py:20 msgid "" "MiniDLNA is a simple media server software, with the aim of being fully " "compliant with DLNA/UPnP-AV clients. The MiniDLNA daemon serves media files " @@ -3403,19 +3387,19 @@ msgstr "" msgid "Services" msgstr "" -#: plinth/modules/networks/__init__.py:35 +#: plinth/modules/networks/__init__.py:34 msgid "" "Configure network devices. Connect to the Internet via Ethernet, Wi-Fi or " "PPPoE. Share that connection with other devices on the network." msgstr "" -#: plinth/modules/networks/__init__.py:37 +#: plinth/modules/networks/__init__.py:36 msgid "" "Devices administered through other methods may not be available for " "configuration here." msgstr "" -#: plinth/modules/networks/__init__.py:58 +#: plinth/modules/networks/__init__.py:57 msgid "Networks" msgstr "" @@ -3761,7 +3745,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:36 #: plinth/modules/wireguard/templates/wireguard_show_client.html:72 #: plinth/modules/wireguard/templates/wireguard_show_server.html:73 -#: plinth/templates/base.html:156 plinth/templates/base.html:157 +#: plinth/templates/base.html:159 plinth/templates/base.html:160 msgid "Edit" msgstr "" @@ -3866,7 +3850,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:175 #: plinth/modules/networks/templates/connection_show.html:218 -#: plinth/modules/shadowsocks/forms.py:49 +#: plinth/modules/shadowsocks/forms.py:48 msgid "Method" msgstr "" @@ -3882,7 +3866,7 @@ msgstr "" #: plinth/modules/networks/templates/connection_show.html:207 #: plinth/modules/networks/templates/connection_show.html:248 -#: plinth/modules/storage/forms.py:138 +#: plinth/modules/storage/forms.py:132 msgid "Default" msgstr "" @@ -3895,7 +3879,7 @@ msgid "This connection is not active." msgstr "" #: plinth/modules/networks/templates/connection_show.html:259 -#: plinth/modules/security/__init__.py:42 +#: plinth/modules/security/__init__.py:34 msgid "Security" msgstr "" @@ -4431,7 +4415,7 @@ msgstr "" msgid "Failed to delete connection: Connection not found." msgstr "" -#: plinth/modules/openvpn/__init__.py:25 +#: plinth/modules/openvpn/__init__.py:20 #, python-brace-format msgid "" "Virtual Private Network (VPN) is a technique for securely connecting two " @@ -4442,20 +4426,20 @@ msgid "" "security and anonymity." msgstr "" -#: plinth/modules/openvpn/__init__.py:53 +#: plinth/modules/openvpn/__init__.py:43 msgid "Connect to VPN services" msgstr "" -#: plinth/modules/openvpn/__init__.py:56 plinth/modules/openvpn/manifest.py:17 +#: plinth/modules/openvpn/__init__.py:46 plinth/modules/openvpn/manifest.py:17 msgid "OpenVPN" msgstr "" -#: plinth/modules/openvpn/__init__.py:57 +#: plinth/modules/openvpn/__init__.py:47 #: plinth/modules/wireguard/__init__.py:49 msgid "Virtual Private Network" msgstr "" -#: plinth/modules/openvpn/__init__.py:68 +#: plinth/modules/openvpn/__init__.py:58 #, python-brace-format msgid "" "Download Profile" @@ -4465,61 +4449,29 @@ msgstr "" msgid "Tunnelblick" msgstr "" -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:7 -msgid "Migrate to ECC" -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:10 -msgid "" -"Your OpenVPN installation is currently using RSA. Switching to the modern " -"Elliptic Curve Cryptography improves speed of establishing a connection and " -"security. This operation is irreversible. It should only take a few minutes " -"on most single board computers." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:19 -#, python-format -msgid "" -"All new installations of OpenVPN on %(box_name)s will use ECC by default. We " -"recommend migrating as soon as possible." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:26 -#, python-format -msgid "" -"Warning: Existing client profiles will be invalidated by this " -"operation. All OpenVPN users on %(box_name)s must download their new " -"profiles. OpenVPN clients compatible with ECC should be used to connect to " -"this server." -msgstr "" - -#: plinth/modules/openvpn/templates/migrate_to_ecc.html:38 -msgid "Migrate" -msgstr "" - -#: plinth/modules/openvpn/templates/openvpn.html:22 +#: plinth/modules/openvpn/templates/openvpn.html:12 msgid "Profile" msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:25 +#: plinth/modules/openvpn/templates/openvpn.html:15 #, python-format msgid "" "To connect to %(box_name)s's VPN, you need to download a profile and feed it " -"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " -"available for most platforms. Click \"Learn more...\" above for recommended " +"to an OpenVPN client on your mobile or desktop machine. OpenVPN Clients are " +"available for most platforms. Click \"Learn more...\" above for recommended " "clients and instructions on how to configure them." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:35 +#: plinth/modules/openvpn/templates/openvpn.html:24 #, python-format -msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." +msgid "Profile is specific to each user of %(box_name)s. Keep it a secret." msgstr "" -#: plinth/modules/openvpn/templates/openvpn.html:46 +#: plinth/modules/openvpn/templates/openvpn.html:34 msgid "Download my profile" msgstr "" -#: plinth/modules/pagekite/__init__.py:21 +#: plinth/modules/pagekite/__init__.py:19 #, python-brace-format msgid "" "PageKite is a system for exposing {box_name} services when you don't have a " @@ -4528,33 +4480,33 @@ msgid "" "following situations:" msgstr "" -#: plinth/modules/pagekite/__init__.py:26 +#: plinth/modules/pagekite/__init__.py:24 #, python-brace-format msgid "{box_name} is behind a restricted firewall." msgstr "" -#: plinth/modules/pagekite/__init__.py:29 +#: plinth/modules/pagekite/__init__.py:27 #, python-brace-format msgid "{box_name} is connected to a (wireless) router which you don't control." msgstr "" -#: plinth/modules/pagekite/__init__.py:31 +#: plinth/modules/pagekite/__init__.py:29 msgid "" "Your ISP does not provide you an external IP address and instead provides " "Internet connection through NAT." msgstr "" -#: plinth/modules/pagekite/__init__.py:33 +#: plinth/modules/pagekite/__init__.py:31 msgid "" "Your ISP does not provide you a static IP address and your IP address " "changes every time you connect to Internet." msgstr "" -#: plinth/modules/pagekite/__init__.py:35 +#: plinth/modules/pagekite/__init__.py:33 msgid "Your ISP limits incoming connections." msgstr "" -#: plinth/modules/pagekite/__init__.py:37 +#: plinth/modules/pagekite/__init__.py:35 #, python-brace-format msgid "" "PageKite works around NAT, firewalls and IP address limitations by using a " @@ -4563,87 +4515,87 @@ msgid "" "the future it might be possible to use your buddy's {box_name} for this." msgstr "" -#: plinth/modules/pagekite/__init__.py:61 +#: plinth/modules/pagekite/__init__.py:59 msgid "PageKite" msgstr "" -#: plinth/modules/pagekite/__init__.py:62 +#: plinth/modules/pagekite/__init__.py:60 msgid "Public Visibility" msgstr "" -#: plinth/modules/pagekite/__init__.py:75 +#: plinth/modules/pagekite/__init__.py:73 msgid "PageKite Domain" msgstr "" -#: plinth/modules/pagekite/forms.py:32 +#: plinth/modules/pagekite/forms.py:30 msgid "Server domain" msgstr "" -#: plinth/modules/pagekite/forms.py:34 +#: plinth/modules/pagekite/forms.py:32 msgid "" "Select your pagekite server. Set \"pagekite.net\" to use the default " "pagekite.net server." msgstr "" -#: plinth/modules/pagekite/forms.py:37 plinth/modules/shadowsocks/forms.py:40 +#: plinth/modules/pagekite/forms.py:35 plinth/modules/shadowsocks/forms.py:39 msgid "Server port" msgstr "" -#: plinth/modules/pagekite/forms.py:38 +#: plinth/modules/pagekite/forms.py:36 msgid "Port of your pagekite server (default: 80)" msgstr "" -#: plinth/modules/pagekite/forms.py:40 +#: plinth/modules/pagekite/forms.py:38 msgid "Kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:41 +#: plinth/modules/pagekite/forms.py:39 msgid "Example: mybox.pagekite.me" msgstr "" -#: plinth/modules/pagekite/forms.py:43 +#: plinth/modules/pagekite/forms.py:41 msgid "Invalid kite name" msgstr "" -#: plinth/modules/pagekite/forms.py:47 +#: plinth/modules/pagekite/forms.py:45 msgid "Kite secret" msgstr "" -#: plinth/modules/pagekite/forms.py:48 +#: plinth/modules/pagekite/forms.py:46 msgid "" "A secret associated with the kite or the default secret for your account if " "no secret is set on the kite." msgstr "" -#: plinth/modules/pagekite/forms.py:88 +#: plinth/modules/pagekite/forms.py:85 msgid "protocol" msgstr "" -#: plinth/modules/pagekite/forms.py:91 +#: plinth/modules/pagekite/forms.py:88 msgid "external (frontend) port" msgstr "" -#: plinth/modules/pagekite/forms.py:94 +#: plinth/modules/pagekite/forms.py:91 msgid "internal (freedombox) port" msgstr "" -#: plinth/modules/pagekite/forms.py:95 +#: plinth/modules/pagekite/forms.py:92 msgid "Enable Subdomains" msgstr "" -#: plinth/modules/pagekite/forms.py:130 +#: plinth/modules/pagekite/forms.py:127 msgid "Deleted custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:164 +#: plinth/modules/pagekite/forms.py:161 msgid "This service is already available as a standard service." msgstr "" -#: plinth/modules/pagekite/forms.py:172 +#: plinth/modules/pagekite/forms.py:169 msgid "Added custom service" msgstr "" -#: plinth/modules/pagekite/forms.py:175 +#: plinth/modules/pagekite/forms.py:172 msgid "This service already exists" msgstr "" @@ -4677,29 +4629,29 @@ msgid "" "HTTPS on ports other than 443 is known to cause problems." msgstr "" -#: plinth/modules/pagekite/utils.py:46 +#: plinth/modules/pagekite/utils.py:45 msgid "Web Server (HTTP)" msgstr "" -#: plinth/modules/pagekite/utils.py:48 +#: plinth/modules/pagekite/utils.py:47 #, python-brace-format msgid "Site will be available at http://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:60 +#: plinth/modules/pagekite/utils.py:59 msgid "Web Server (HTTPS)" msgstr "" -#: plinth/modules/pagekite/utils.py:62 +#: plinth/modules/pagekite/utils.py:61 #, python-brace-format msgid "Site will be available at https://{0}" msgstr "" -#: plinth/modules/pagekite/utils.py:74 +#: plinth/modules/pagekite/utils.py:73 msgid "Secure Shell (SSH)" msgstr "" -#: plinth/modules/pagekite/utils.py:76 +#: plinth/modules/pagekite/utils.py:75 msgid "" "See SSH client setup instructions" @@ -4741,8 +4693,8 @@ msgid "" "finished before shutting down or restarting." msgstr "" -#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:171 -#: plinth/templates/base.html:172 +#: plinth/modules/power/templates/power.html:22 plinth/templates/base.html:174 +#: plinth/templates/base.html:175 msgid "Restart" msgstr "" @@ -4784,6 +4736,37 @@ msgstr "" msgid "Shut Down Now" msgstr "" +#: plinth/modules/privacy/__init__.py:15 +msgid "Manage system-wide privacy settings." +msgstr "" + +#: plinth/modules/privacy/__init__.py:32 plinth/modules/privacy/__init__.py:64 +msgid "Privacy" +msgstr "" + +#: plinth/modules/privacy/__init__.py:62 +msgid "Please update privacy settings to match your preferences." +msgstr "" + +#: plinth/modules/privacy/__init__.py:67 +msgid "Review privacy setting" +msgstr "" + +#: plinth/modules/privacy/forms.py:15 +msgid "Periodically submit a list of apps used (suggested)" +msgstr "" + +#: plinth/modules/privacy/forms.py:17 +#, python-brace-format +msgid "" +"Help Debian/{box_name} developers by participating in the Popularity Contest " +"package survey program. When enabled, a list of apps used on this system " +"will be anonymously submitted to Debian every week. Statistics for the data " +"collected are publicly available at popcon.debian.org. Submission happens over the Tor " +"network for additional anonymity if Tor app is enabled." +msgstr "" + #: plinth/modules/privoxy/__init__.py:23 msgid "" "Privoxy is a non-caching web proxy with advanced filtering capabilities for " @@ -4815,7 +4798,7 @@ msgstr "" msgid "Access {url} with proxy {proxy} on tcp{kind}" msgstr "" -#: plinth/modules/quassel/__init__.py:27 +#: plinth/modules/quassel/__init__.py:24 #, python-brace-format msgid "" "Quassel is an IRC application that is split into two parts, a \"core\" and a " @@ -4826,7 +4809,7 @@ msgid "" "connect and disconnect from it." msgstr "" -#: plinth/modules/quassel/__init__.py:34 +#: plinth/modules/quassel/__init__.py:31 msgid "" "You can connect to your Quassel core on the default Quassel port 4242. " "Clients to connect to Quassel from your mobile devices are available." msgstr "" -#: plinth/modules/quassel/__init__.py:54 plinth/modules/quassel/manifest.py:9 +#: plinth/modules/quassel/__init__.py:51 plinth/modules/quassel/manifest.py:9 msgid "Quassel" msgstr "" -#: plinth/modules/quassel/__init__.py:55 +#: plinth/modules/quassel/__init__.py:52 msgid "IRC Client" msgstr "" @@ -4846,7 +4829,7 @@ msgstr "" msgid "Quasseldroid" msgstr "" -#: plinth/modules/radicale/__init__.py:25 +#: plinth/modules/radicale/__init__.py:24 #, python-brace-format msgid "" "Radicale is a CalDAV and CardDAV server. It allows synchronization and " @@ -4856,19 +4839,19 @@ msgid "" "{box_name} login." msgstr "" -#: plinth/modules/radicale/__init__.py:31 +#: plinth/modules/radicale/__init__.py:30 msgid "" "Radicale provides a basic web interface, which only supports creating new " "calendars and addressbooks. It does not support adding events or contacts, " "which must be done using a separate client." msgstr "" -#: plinth/modules/radicale/__init__.py:53 +#: plinth/modules/radicale/__init__.py:52 #: plinth/modules/radicale/manifest.py:74 msgid "Radicale" msgstr "" -#: plinth/modules/radicale/__init__.py:54 +#: plinth/modules/radicale/__init__.py:53 msgid "Calendar and Addressbook" msgstr "" @@ -4927,7 +4910,7 @@ msgid "" "existing calendars and address books." msgstr "" -#: plinth/modules/radicale/views.py:35 +#: plinth/modules/radicale/views.py:32 msgid "Access rights configuration updated" msgstr "" @@ -4999,7 +4982,7 @@ msgid "" "your {box_name} credentials." msgstr "" -#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:48 +#: plinth/modules/rssbridge/__init__.py:45 plinth/modules/ttrss/__init__.py:45 msgid "Read and subscribe to news feeds" msgstr "" @@ -5012,13 +4995,13 @@ msgstr "" msgid "RSS Feed Generator" msgstr "" -#: plinth/modules/samba/__init__.py:27 +#: plinth/modules/samba/__init__.py:23 msgid "" "Samba allows to share files and folders between FreedomBox and other " "computers in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:30 +#: plinth/modules/samba/__init__.py:26 #, python-brace-format msgid "" "After installation, you can choose which disks to use for sharing. Enabled " @@ -5027,31 +5010,31 @@ msgid "" "There are three types of shares you can choose from: " msgstr "" -#: plinth/modules/samba/__init__.py:35 +#: plinth/modules/samba/__init__.py:31 msgid "Open share - accessible to everyone in your local network." msgstr "" -#: plinth/modules/samba/__init__.py:36 +#: plinth/modules/samba/__init__.py:32 msgid "" "Group share - accessible only to FreedomBox users who are in the freedombox-" "share group." msgstr "" -#: plinth/modules/samba/__init__.py:38 +#: plinth/modules/samba/__init__.py:34 msgid "" "Home share - every user in the freedombox-share group can have their own " "private space." msgstr "" -#: plinth/modules/samba/__init__.py:54 +#: plinth/modules/samba/__init__.py:50 msgid "Access to the private shares" msgstr "" -#: plinth/modules/samba/__init__.py:57 +#: plinth/modules/samba/__init__.py:53 msgid "Samba" msgstr "" -#: plinth/modules/samba/__init__.py:58 +#: plinth/modules/samba/__init__.py:54 msgid "Network File Storage" msgstr "" @@ -5129,15 +5112,15 @@ msgstr "" msgid "Action" msgstr "" -#: plinth/modules/samba/views.py:34 +#: plinth/modules/samba/views.py:33 msgid "FreedomBox OS disk" msgstr "" -#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:146 +#: plinth/modules/samba/views.py:60 plinth/modules/storage/forms.py:140 msgid "Open Share" msgstr "" -#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:144 +#: plinth/modules/samba/views.py:64 plinth/modules/storage/forms.py:138 msgid "Group Share" msgstr "" @@ -5163,51 +5146,51 @@ msgstr "" msgid "Error disabling share: {error_message}" msgstr "" -#: plinth/modules/searx/__init__.py:22 +#: plinth/modules/searx/__init__.py:19 msgid "" "Searx is a privacy-respecting Internet metasearch engine. It aggregrates and " "displays results from multiple search engines." msgstr "" -#: plinth/modules/searx/__init__.py:24 +#: plinth/modules/searx/__init__.py:21 msgid "" "Searx can be used to avoid tracking and profiling by search engines. It " "stores no cookies by default." msgstr "" -#: plinth/modules/searx/__init__.py:40 +#: plinth/modules/searx/__init__.py:37 msgid "Search the web" msgstr "" -#: plinth/modules/searx/__init__.py:43 plinth/modules/searx/manifest.py:6 +#: plinth/modules/searx/__init__.py:40 plinth/modules/searx/manifest.py:6 msgid "Searx" msgstr "" -#: plinth/modules/searx/__init__.py:44 +#: plinth/modules/searx/__init__.py:41 msgid "Web Search" msgstr "" -#: plinth/modules/searx/forms.py:13 +#: plinth/modules/searx/forms.py:12 msgid "Safe Search" msgstr "" -#: plinth/modules/searx/forms.py:14 +#: plinth/modules/searx/forms.py:13 msgid "Select the default family filter to apply to your search results." msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Moderate" msgstr "" -#: plinth/modules/searx/forms.py:15 +#: plinth/modules/searx/forms.py:14 msgid "Strict" msgstr "" -#: plinth/modules/searx/forms.py:18 +#: plinth/modules/searx/forms.py:17 msgid "Allow Public Access" msgstr "" -#: plinth/modules/searx/forms.py:19 +#: plinth/modules/searx/forms.py:18 msgid "Allow this application to be used by anyone who can reach it." msgstr "" @@ -5360,14 +5343,14 @@ msgstr "" msgid "Shaarlier" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:21 +#: plinth/modules/shadowsocks/__init__.py:18 msgid "" "Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to protect " "your Internet traffic. It can be used to bypass Internet filtering and " "censorship." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:25 +#: plinth/modules/shadowsocks/__init__.py:22 #, python-brace-format msgid "" "Your {box_name} can run a Shadowsocks client, that can connect to a " @@ -5376,97 +5359,97 @@ msgid "" "the Shadowsocks server." msgstr "" -#: plinth/modules/shadowsocks/__init__.py:30 +#: plinth/modules/shadowsocks/__init__.py:27 msgid "" "To use Shadowsocks after setup, set the SOCKS5 proxy URL in your device, " "browser or application to http://freedombox_address:1080/" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:49 +#: plinth/modules/shadowsocks/__init__.py:46 msgid "Shadowsocks" msgstr "" -#: plinth/modules/shadowsocks/__init__.py:51 +#: plinth/modules/shadowsocks/__init__.py:48 msgid "Socks5 Proxy" msgstr "" -#: plinth/modules/shadowsocks/forms.py:12 -#: plinth/modules/shadowsocks/forms.py:13 +#: plinth/modules/shadowsocks/forms.py:10 +#: plinth/modules/shadowsocks/forms.py:11 msgid "Recommended" msgstr "" -#: plinth/modules/shadowsocks/forms.py:37 +#: plinth/modules/shadowsocks/forms.py:36 msgid "Server" msgstr "" -#: plinth/modules/shadowsocks/forms.py:38 +#: plinth/modules/shadowsocks/forms.py:37 msgid "Server hostname or IP address" msgstr "" -#: plinth/modules/shadowsocks/forms.py:42 +#: plinth/modules/shadowsocks/forms.py:41 msgid "Server port number" msgstr "" -#: plinth/modules/shadowsocks/forms.py:45 +#: plinth/modules/shadowsocks/forms.py:44 msgid "Password used to encrypt data. Must match server password." msgstr "" -#: plinth/modules/shadowsocks/forms.py:50 +#: plinth/modules/shadowsocks/forms.py:49 msgid "Encryption method. Must match setting on server." msgstr "" -#: plinth/modules/sharing/__init__.py:21 +#: plinth/modules/sharing/__init__.py:16 #, python-brace-format msgid "" "Sharing allows you to share files and folders on your {box_name} over the " "web with chosen groups of users." msgstr "" -#: plinth/modules/sharing/__init__.py:38 +#: plinth/modules/sharing/__init__.py:33 msgid "Sharing" msgstr "" -#: plinth/modules/sharing/forms.py:18 +#: plinth/modules/sharing/forms.py:17 msgid "Name of the share" msgstr "" -#: plinth/modules/sharing/forms.py:20 +#: plinth/modules/sharing/forms.py:19 msgid "" "A lowercase alpha-numeric string that uniquely identifies a share. Example: " "media." msgstr "" -#: plinth/modules/sharing/forms.py:24 +#: plinth/modules/sharing/forms.py:23 msgid "Path to share" msgstr "" -#: plinth/modules/sharing/forms.py:25 +#: plinth/modules/sharing/forms.py:24 msgid "Disk path to a folder on this server that you intend to share." msgstr "" -#: plinth/modules/sharing/forms.py:28 +#: plinth/modules/sharing/forms.py:27 msgid "Public share" msgstr "" -#: plinth/modules/sharing/forms.py:29 +#: plinth/modules/sharing/forms.py:28 msgid "Make files in this folder available to anyone with the link." msgstr "" -#: plinth/modules/sharing/forms.py:34 +#: plinth/modules/sharing/forms.py:33 msgid "User groups that can read the files in the share:" msgstr "" -#: plinth/modules/sharing/forms.py:36 +#: plinth/modules/sharing/forms.py:35 msgid "" "Users of the selected user groups will be able to read the files in the " "share." msgstr "" -#: plinth/modules/sharing/forms.py:52 +#: plinth/modules/sharing/forms.py:51 msgid "A share with this name already exists." msgstr "" -#: plinth/modules/sharing/forms.py:63 +#: plinth/modules/sharing/forms.py:62 msgid "Shares should be either public or shared with at least one group" msgstr "" @@ -5503,26 +5486,26 @@ msgstr "" msgid "Add Share" msgstr "" -#: plinth/modules/sharing/views.py:59 +#: plinth/modules/sharing/views.py:60 msgid "Share edited." msgstr "" -#: plinth/modules/sharing/views.py:64 +#: plinth/modules/sharing/views.py:65 msgid "Edit Share" msgstr "" -#: plinth/modules/sharing/views.py:95 +#: plinth/modules/sharing/views.py:96 msgid "Share deleted." msgstr "" -#: plinth/modules/snapshot/__init__.py:22 +#: plinth/modules/snapshot/__init__.py:18 msgid "" "Snapshots allows creating and managing btrfs file system snapshots. These " "can be used to roll back the system to a previously known good state in case " "of unwanted changes to the system." msgstr "" -#: plinth/modules/snapshot/__init__.py:26 +#: plinth/modules/snapshot/__init__.py:22 #, no-python-format msgid "" "Snapshots are taken periodically (called timeline snapshots) and also before " @@ -5530,14 +5513,14 @@ msgid "" "cleaned up according to the settings below." msgstr "" -#: plinth/modules/snapshot/__init__.py:29 +#: plinth/modules/snapshot/__init__.py:25 msgid "" "Snapshots currently work on btrfs file systems only and on the root " "partition only. Snapshots are not a replacement for backups since they can only be stored on the same partition. " msgstr "" -#: plinth/modules/snapshot/__init__.py:54 +#: plinth/modules/snapshot/__init__.py:50 msgid "Storage Snapshots" msgstr "" @@ -5631,7 +5614,7 @@ msgstr "" #: plinth/modules/snapshot/templates/snapshot_delete_selected.html:42 #: plinth/modules/snapshot/templates/snapshot_manage.html:20 -#: plinth/modules/snapshot/views.py:203 +#: plinth/modules/snapshot/views.py:194 msgid "Delete Snapshots" msgstr "" @@ -5679,57 +5662,57 @@ msgstr "" msgid "Rollback to Snapshot #%(number)s" msgstr "" -#: plinth/modules/snapshot/views.py:29 +#: plinth/modules/snapshot/views.py:24 msgid "manually created" msgstr "" -#: plinth/modules/snapshot/views.py:30 +#: plinth/modules/snapshot/views.py:25 msgid "timeline" msgstr "" -#: plinth/modules/snapshot/views.py:31 +#: plinth/modules/snapshot/views.py:26 msgid "apt" msgstr "" -#: plinth/modules/snapshot/views.py:41 +#: plinth/modules/snapshot/views.py:36 msgid "Manage Snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:94 +#: plinth/modules/snapshot/views.py:89 msgid "Created snapshot." msgstr "" -#: plinth/modules/snapshot/views.py:158 +#: plinth/modules/snapshot/views.py:151 msgid "Storage snapshots configuration updated" msgstr "" -#: plinth/modules/snapshot/views.py:162 +#: plinth/modules/snapshot/views.py:155 #, python-brace-format msgid "Action error: {0} [{1}] [{2}]" msgstr "" -#: plinth/modules/snapshot/views.py:190 +#: plinth/modules/snapshot/views.py:181 msgid "Deleted selected snapshots" msgstr "" -#: plinth/modules/snapshot/views.py:195 +#: plinth/modules/snapshot/views.py:186 msgid "Snapshot is currently in use. Please try again later." msgstr "" -#: plinth/modules/snapshot/views.py:214 +#: plinth/modules/snapshot/views.py:205 #, python-brace-format msgid "Rolled back to snapshot #{number}." msgstr "" -#: plinth/modules/snapshot/views.py:217 +#: plinth/modules/snapshot/views.py:208 msgid "The system must be restarted to complete the rollback." msgstr "" -#: plinth/modules/snapshot/views.py:229 +#: plinth/modules/snapshot/views.py:218 msgid "Rollback to Snapshot" msgstr "" -#: plinth/modules/ssh/__init__.py:23 +#: plinth/modules/ssh/__init__.py:20 msgid "" "A Secure Shell server uses the secure shell protocol to accept connections " "from remote computers. An authorized remote computer can perform " @@ -5737,7 +5720,7 @@ msgid "" "connections." msgstr "" -#: plinth/modules/ssh/__init__.py:43 +#: plinth/modules/ssh/__init__.py:40 msgid "Secure Shell (SSH) Server" msgstr "" @@ -5770,14 +5753,6 @@ msgstr "" msgid "Fingerprint" msgstr "" -#: plinth/modules/ssh/views.py:48 -msgid "SSH authentication with password disabled." -msgstr "" - -#: plinth/modules/ssh/views.py:51 -msgid "SSH authentication with password enabled." -msgstr "" - #: plinth/modules/sso/__init__.py:26 msgid "Single Sign On" msgstr "" @@ -5790,7 +5765,7 @@ msgstr "" msgid "Logged out successfully." msgstr "" -#: plinth/modules/storage/__init__.py:26 +#: plinth/modules/storage/__init__.py:22 #, python-brace-format msgid "" "This module allows you to manage storage media attached to your {box_name}. " @@ -5798,143 +5773,143 @@ msgid "" "media, expand the root partition etc." msgstr "" -#: plinth/modules/storage/__init__.py:49 plinth/modules/storage/__init__.py:319 -#: plinth/modules/storage/__init__.py:350 +#: plinth/modules/storage/__init__.py:45 plinth/modules/storage/__init__.py:306 +#: plinth/modules/storage/__init__.py:337 msgid "Storage" msgstr "" -#: plinth/modules/storage/__init__.py:227 +#: plinth/modules/storage/__init__.py:214 #, python-brace-format msgid "{disk_size:.1f} bytes" msgstr "" -#: plinth/modules/storage/__init__.py:231 +#: plinth/modules/storage/__init__.py:218 #, python-brace-format msgid "{disk_size:.1f} KiB" msgstr "" -#: plinth/modules/storage/__init__.py:235 +#: plinth/modules/storage/__init__.py:222 #, python-brace-format msgid "{disk_size:.1f} MiB" msgstr "" -#: plinth/modules/storage/__init__.py:239 +#: plinth/modules/storage/__init__.py:226 #, python-brace-format msgid "{disk_size:.1f} GiB" msgstr "" -#: plinth/modules/storage/__init__.py:242 +#: plinth/modules/storage/__init__.py:229 #, python-brace-format msgid "{disk_size:.1f} TiB" msgstr "" -#: plinth/modules/storage/__init__.py:254 +#: plinth/modules/storage/__init__.py:241 msgid "The operation failed." msgstr "" -#: plinth/modules/storage/__init__.py:256 +#: plinth/modules/storage/__init__.py:243 msgid "The operation was cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:258 +#: plinth/modules/storage/__init__.py:245 msgid "The device is already unmounting." msgstr "" -#: plinth/modules/storage/__init__.py:260 +#: plinth/modules/storage/__init__.py:247 msgid "The operation is not supported due to missing driver/tool support." msgstr "" -#: plinth/modules/storage/__init__.py:263 +#: plinth/modules/storage/__init__.py:250 msgid "The operation timed out." msgstr "" -#: plinth/modules/storage/__init__.py:265 +#: plinth/modules/storage/__init__.py:252 msgid "The operation would wake up a disk that is in a deep-sleep state." msgstr "" -#: plinth/modules/storage/__init__.py:268 +#: plinth/modules/storage/__init__.py:255 msgid "Attempting to unmount a device that is busy." msgstr "" -#: plinth/modules/storage/__init__.py:270 +#: plinth/modules/storage/__init__.py:257 msgid "The operation has already been cancelled." msgstr "" -#: plinth/modules/storage/__init__.py:272 -#: plinth/modules/storage/__init__.py:274 -#: plinth/modules/storage/__init__.py:276 +#: plinth/modules/storage/__init__.py:259 +#: plinth/modules/storage/__init__.py:261 +#: plinth/modules/storage/__init__.py:263 msgid "Not authorized to perform the requested operation." msgstr "" -#: plinth/modules/storage/__init__.py:278 +#: plinth/modules/storage/__init__.py:265 msgid "The device is already mounted." msgstr "" -#: plinth/modules/storage/__init__.py:280 +#: plinth/modules/storage/__init__.py:267 msgid "The device is not mounted." msgstr "" -#: plinth/modules/storage/__init__.py:282 +#: plinth/modules/storage/__init__.py:269 msgid "Not permitted to use the requested option." msgstr "" -#: plinth/modules/storage/__init__.py:284 +#: plinth/modules/storage/__init__.py:271 msgid "The device is mounted by another user." msgstr "" -#: plinth/modules/storage/__init__.py:314 +#: plinth/modules/storage/__init__.py:301 #, no-python-format, python-brace-format msgid "Low space on system partition: {percent_used}% used, {free_space} free." msgstr "" -#: plinth/modules/storage/__init__.py:316 +#: plinth/modules/storage/__init__.py:303 msgid "Low disk space" msgstr "" -#: plinth/modules/storage/__init__.py:344 +#: plinth/modules/storage/__init__.py:331 msgid "Disk failure imminent" msgstr "" -#: plinth/modules/storage/__init__.py:346 +#: plinth/modules/storage/__init__.py:333 #, python-brace-format msgid "" "Disk {id} is reporting that it is likely to fail in the near future. Copy " "any data while you still can and replace the drive." msgstr "" -#: plinth/modules/storage/forms.py:62 +#: plinth/modules/storage/forms.py:63 msgid "Invalid directory name." msgstr "" -#: plinth/modules/storage/forms.py:79 +#: plinth/modules/storage/forms.py:73 msgid "Directory does not exist." msgstr "" -#: plinth/modules/storage/forms.py:82 +#: plinth/modules/storage/forms.py:75 msgid "Path is not a directory." msgstr "" -#: plinth/modules/storage/forms.py:85 +#: plinth/modules/storage/forms.py:79 msgid "Directory is not readable by the user." msgstr "" -#: plinth/modules/storage/forms.py:88 +#: plinth/modules/storage/forms.py:82 msgid "Directory is not writable by the user." msgstr "" -#: plinth/modules/storage/forms.py:93 +#: plinth/modules/storage/forms.py:87 msgid "Directory" msgstr "" -#: plinth/modules/storage/forms.py:95 +#: plinth/modules/storage/forms.py:89 msgid "Subdirectory (optional)" msgstr "" -#: plinth/modules/storage/forms.py:142 +#: plinth/modules/storage/forms.py:136 msgid "Share" msgstr "" -#: plinth/modules/storage/forms.py:150 +#: plinth/modules/storage/forms.py:144 msgid "Other directory (specify below)" msgstr "" @@ -5968,7 +5943,7 @@ msgstr "" #: plinth/modules/storage/templates/storage.html:89 #: plinth/modules/storage/templates/storage_expand.html:24 -#: plinth/modules/storage/views.py:58 +#: plinth/modules/storage/views.py:55 msgid "Expand Root Partition" msgstr "" @@ -5986,30 +5961,30 @@ msgid "" "root partition." msgstr "" -#: plinth/modules/storage/views.py:70 +#: plinth/modules/storage/views.py:67 #, python-brace-format msgid "Error expanding partition: {exception}" msgstr "" -#: plinth/modules/storage/views.py:73 +#: plinth/modules/storage/views.py:70 msgid "Partition expanded successfully." msgstr "" -#: plinth/modules/storage/views.py:91 +#: plinth/modules/storage/views.py:87 #, python-brace-format msgid "{drive_vendor} {drive_model} can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:95 +#: plinth/modules/storage/views.py:91 msgid "Device can be safely unplugged." msgstr "" -#: plinth/modules/storage/views.py:102 +#: plinth/modules/storage/views.py:98 #, python-brace-format msgid "Error ejecting device: {error_message}" msgstr "" -#: plinth/modules/syncthing/__init__.py:23 +#: plinth/modules/syncthing/__init__.py:21 msgid "" "Syncthing is an application to synchronize files across multiple devices, e." "g. your desktop computer and mobile phone. Creation, modification, or " @@ -6017,7 +5992,7 @@ msgid "" "other devices that also run Syncthing." msgstr "" -#: plinth/modules/syncthing/__init__.py:28 +#: plinth/modules/syncthing/__init__.py:26 #, python-brace-format msgid "" "Running Syncthing on {box_name} provides an extra synchronization point for " @@ -6029,20 +6004,20 @@ msgid "" "\"syncthing-access\" group." msgstr "" -#: plinth/modules/syncthing/__init__.py:55 +#: plinth/modules/syncthing/__init__.py:53 msgid "Administer Syncthing application" msgstr "" -#: plinth/modules/syncthing/__init__.py:59 +#: plinth/modules/syncthing/__init__.py:57 #: plinth/modules/syncthing/manifest.py:12 msgid "Syncthing" msgstr "" -#: plinth/modules/syncthing/__init__.py:60 +#: plinth/modules/syncthing/__init__.py:58 msgid "File Synchronization" msgstr "" -#: plinth/modules/tor/__init__.py:27 +#: plinth/modules/tor/__init__.py:23 msgid "" "Tor is an anonymous communication system. You can learn more about it from " "the Tor Project website. For " @@ -6051,47 +6026,47 @@ msgid "" "\">Tor Browser." msgstr "" -#: plinth/modules/tor/__init__.py:34 +#: plinth/modules/tor/__init__.py:30 #, python-brace-format msgid "" "A Tor SOCKS port is available on your {box_name} for internal networks on " "TCP port 9050." msgstr "" -#: plinth/modules/tor/__init__.py:52 +#: plinth/modules/tor/__init__.py:48 msgid "Tor" msgstr "" -#: plinth/modules/tor/__init__.py:69 +#: plinth/modules/tor/__init__.py:65 msgid "Tor Onion Service" msgstr "" -#: plinth/modules/tor/__init__.py:73 +#: plinth/modules/tor/__init__.py:69 msgid "Tor Socks Proxy" msgstr "" -#: plinth/modules/tor/__init__.py:77 +#: plinth/modules/tor/__init__.py:73 msgid "Tor Bridge Relay" msgstr "" -#: plinth/modules/tor/__init__.py:132 +#: plinth/modules/tor/__init__.py:127 msgid "Tor relay port available" msgstr "" -#: plinth/modules/tor/__init__.py:142 +#: plinth/modules/tor/__init__.py:137 msgid "Obfs3 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:152 +#: plinth/modules/tor/__init__.py:147 msgid "Obfs4 transport registered" msgstr "" -#: plinth/modules/tor/__init__.py:220 +#: plinth/modules/tor/__init__.py:212 #, python-brace-format msgid "Access URL {url} on tcp{kind} via Tor" msgstr "" -#: plinth/modules/tor/__init__.py:231 +#: plinth/modules/tor/__init__.py:223 #, python-brace-format msgid "Confirm Tor usage at {url} on tcp{kind}" msgstr "" @@ -6189,13 +6164,13 @@ msgstr "" msgid "Ports" msgstr "" -#: plinth/modules/tor/views.py:55 +#: plinth/modules/tor/views.py:53 #, fuzzy #| msgid "An error occurred during configuration." msgid "Updating configuration" msgstr "設置過程中發生錯誤。" -#: plinth/modules/tor/views.py:72 +#: plinth/modules/tor/views.py:70 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error configuring app: {error}" @@ -6253,14 +6228,14 @@ msgstr "" msgid "Transmission" msgstr "" -#: plinth/modules/ttrss/__init__.py:23 +#: plinth/modules/ttrss/__init__.py:20 msgid "" "Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, designed to " "allow reading news from any location, while feeling as close to a real " "desktop application as possible." msgstr "" -#: plinth/modules/ttrss/__init__.py:27 +#: plinth/modules/ttrss/__init__.py:24 #, fuzzy, python-brace-format #| msgid "" #| "It can be accessed by any user on {box_name} " @@ -6272,17 +6247,17 @@ msgstr "" "它可以由 {box_name} 上屬於 admin 群組的 任何使用者存取。" -#: plinth/modules/ttrss/__init__.py:32 +#: plinth/modules/ttrss/__init__.py:29 msgid "" "When using a mobile or desktop application for Tiny Tiny RSS, use the URL /tt-rss-app for connecting." msgstr "" -#: plinth/modules/ttrss/__init__.py:51 plinth/modules/ttrss/manifest.py:18 +#: plinth/modules/ttrss/__init__.py:48 plinth/modules/ttrss/manifest.py:18 msgid "Tiny Tiny RSS" msgstr "" -#: plinth/modules/ttrss/__init__.py:52 +#: plinth/modules/ttrss/__init__.py:49 msgid "News Feed Reader" msgstr "" @@ -6290,12 +6265,12 @@ msgstr "" msgid "Tiny Tiny RSS (Fork)" msgstr "" -#: plinth/modules/upgrades/__init__.py:39 +#: plinth/modules/upgrades/__init__.py:35 #: plinth/modules/upgrades/templates/update-firstboot.html:14 msgid "Check for and apply the latest software and security updates." msgstr "" -#: plinth/modules/upgrades/__init__.py:40 +#: plinth/modules/upgrades/__init__.py:36 msgid "" "Updates are run at 06:00 everyday according to local time zone. Set your " "time zone in Date & Time app. Apps are restarted after update causing them " @@ -6303,33 +6278,33 @@ msgid "" "automatically at 02:00 causing all apps to be unavailable briefly." msgstr "" -#: plinth/modules/upgrades/__init__.py:72 -#: plinth/modules/upgrades/__init__.py:127 +#: plinth/modules/upgrades/__init__.py:64 +#: plinth/modules/upgrades/__init__.py:119 #: plinth/modules/upgrades/templates/update-firstboot-progress.html:11 #: plinth/modules/upgrades/templates/update-firstboot.html:11 msgid "Software Update" msgstr "" -#: plinth/modules/upgrades/__init__.py:130 +#: plinth/modules/upgrades/__init__.py:122 msgid "FreedomBox Updated" msgstr "" -#: plinth/modules/upgrades/__init__.py:222 +#: plinth/modules/upgrades/__init__.py:190 msgid "Could not start distribution update" msgstr "" -#: plinth/modules/upgrades/__init__.py:224 +#: plinth/modules/upgrades/__init__.py:192 msgid "" "There is not enough free space in the root partition to start the " "distribution update. Please ensure at least 5 GB is free. Distribution " "update will be retried after 24 hours, if enabled." msgstr "" -#: plinth/modules/upgrades/__init__.py:235 +#: plinth/modules/upgrades/__init__.py:203 msgid "Distribution update started" msgstr "" -#: plinth/modules/upgrades/__init__.py:237 +#: plinth/modules/upgrades/__init__.py:205 msgid "" "Started update to next stable release. This may take a long time to complete." msgstr "" @@ -6477,51 +6452,51 @@ msgstr "" msgid "Test distribution upgrade now" msgstr "" -#: plinth/modules/upgrades/views.py:68 +#: plinth/modules/upgrades/views.py:71 #, python-brace-format msgid "Error when configuring unattended-upgrades: {error}" msgstr "" -#: plinth/modules/upgrades/views.py:72 +#: plinth/modules/upgrades/views.py:75 msgid "Automatic upgrades enabled" msgstr "" -#: plinth/modules/upgrades/views.py:75 +#: plinth/modules/upgrades/views.py:78 msgid "Automatic upgrades disabled" msgstr "" -#: plinth/modules/upgrades/views.py:83 +#: plinth/modules/upgrades/views.py:86 msgid "Distribution upgrade enabled" msgstr "" -#: plinth/modules/upgrades/views.py:86 +#: plinth/modules/upgrades/views.py:89 msgid "Distribution upgrade disabled" msgstr "" -#: plinth/modules/upgrades/views.py:128 +#: plinth/modules/upgrades/views.py:126 msgid "Upgrade process started." msgstr "" -#: plinth/modules/upgrades/views.py:130 +#: plinth/modules/upgrades/views.py:128 msgid "Starting upgrade failed." msgstr "" -#: plinth/modules/upgrades/views.py:140 +#: plinth/modules/upgrades/views.py:138 msgid "Frequent feature updates activated." msgstr "" -#: plinth/modules/upgrades/views.py:223 +#: plinth/modules/upgrades/views.py:224 msgid "Starting distribution upgrade test." msgstr "" -#: plinth/modules/users/__init__.py:29 +#: plinth/modules/users/__init__.py:28 msgid "" "Create and manage user accounts. These accounts serve as centralized " "authentication mechanism for most apps. Some apps further require a user " "account to be part of a group to authorize the user to access the app." msgstr "" -#: plinth/modules/users/__init__.py:34 +#: plinth/modules/users/__init__.py:33 #, python-brace-format msgid "" "Any user may login to {box_name} web interface to see a list of apps " @@ -6529,15 +6504,15 @@ msgid "" "group may alter apps or system settings." msgstr "" -#: plinth/modules/users/__init__.py:55 +#: plinth/modules/users/__init__.py:54 msgid "Users and Groups" msgstr "" -#: plinth/modules/users/__init__.py:75 +#: plinth/modules/users/__init__.py:74 msgid "Access to all services and system settings" msgstr "" -#: plinth/modules/users/__init__.py:111 +#: plinth/modules/users/__init__.py:110 #, python-brace-format msgid "Check LDAP entry \"{search_item}\"" msgstr "" @@ -6555,21 +6530,21 @@ msgid "" "Required. 150 characters or fewer. English letters, digits and @/./-/_ only." msgstr "" -#: plinth/modules/users/forms.py:78 +#: plinth/modules/users/forms.py:79 msgid "Authorization Password" msgstr "" -#: plinth/modules/users/forms.py:84 +#: plinth/modules/users/forms.py:86 #, python-brace-format msgid "" "Enter the password for user \"{user}\" to authorize account modifications." msgstr "" -#: plinth/modules/users/forms.py:93 +#: plinth/modules/users/forms.py:95 msgid "Invalid password." msgstr "" -#: plinth/modules/users/forms.py:110 +#: plinth/modules/users/forms.py:113 msgid "" "Select which services should be available to the new user. The user will be " "able to log in to services that support single sign-on through LDAP, if they " @@ -6578,12 +6553,12 @@ msgid "" "SSH and have administrative privileges (sudo)." msgstr "" -#: plinth/modules/users/forms.py:155 plinth/modules/users/forms.py:399 +#: plinth/modules/users/forms.py:156 plinth/modules/users/forms.py:374 #, python-brace-format msgid "Creating LDAP user failed: {error}" msgstr "" -#: plinth/modules/users/forms.py:168 +#: plinth/modules/users/forms.py:167 #, python-brace-format msgid "Failed to add new user to {group} group: {error}" msgstr "" @@ -6599,41 +6574,41 @@ msgid "" "line. Blank lines and lines starting with # will be ignored." msgstr "" -#: plinth/modules/users/forms.py:269 +#: plinth/modules/users/forms.py:265 msgid "Renaming LDAP user failed." msgstr "" -#: plinth/modules/users/forms.py:282 +#: plinth/modules/users/forms.py:276 msgid "Failed to remove user from group." msgstr "" -#: plinth/modules/users/forms.py:294 +#: plinth/modules/users/forms.py:286 msgid "Failed to add user to group." msgstr "" -#: plinth/modules/users/forms.py:307 +#: plinth/modules/users/forms.py:293 msgid "Unable to set SSH keys." msgstr "" -#: plinth/modules/users/forms.py:325 +#: plinth/modules/users/forms.py:306 msgid "Failed to change user status." msgstr "" -#: plinth/modules/users/forms.py:370 +#: plinth/modules/users/forms.py:347 msgid "Changing LDAP user password failed." msgstr "" -#: plinth/modules/users/forms.py:410 +#: plinth/modules/users/forms.py:382 #, python-brace-format msgid "Failed to add new user to admin group: {error}" msgstr "" -#: plinth/modules/users/forms.py:429 +#: plinth/modules/users/forms.py:401 #, python-brace-format msgid "Failed to restrict console access: {error}" msgstr "" -#: plinth/modules/users/forms.py:442 +#: plinth/modules/users/forms.py:414 msgid "User account created, you are now logged in" msgstr "" @@ -6650,12 +6625,12 @@ msgstr "" #: plinth/modules/users/templates/users_create.html:19 #: plinth/modules/users/templates/users_list.html:15 #: plinth/modules/users/templates/users_list.html:17 -#: plinth/modules/users/views.py:44 +#: plinth/modules/users/views.py:46 msgid "Create User" msgstr "" #: plinth/modules/users/templates/users_delete.html:11 -#: plinth/modules/users/views.py:134 +#: plinth/modules/users/views.py:138 msgid "Delete User" msgstr "" @@ -6693,17 +6668,17 @@ msgid "The following administrator accounts exist in the system." msgstr "" #: plinth/modules/users/templates/users_firstboot.html:50 -#, python-format, python-brace-format +#, python-format msgid "" "Delete these accounts from command line and refresh the page to create an " "account that is usable with %(box_name)s. On the command line run the " -"command 'echo \"{password}\" | /usr/share/plinth/actions/users remove-user " -"{username}'. If an account is already usable with %(box_name)s, skip this " -"step." +"command \"echo '{\"args\": [\"USERNAME\", \"PASSWORD\"], \"kwargs\": {}}' | " +"sudo /usr/share/plinth/actions/actions users remove_user\". If an account is " +"already usable with %(box_name)s, skip this step." msgstr "" #: plinth/modules/users/templates/users_list.html:11 -#: plinth/modules/users/views.py:61 +#: plinth/modules/users/views.py:64 msgid "Users" msgstr "" @@ -6734,34 +6709,34 @@ msgstr "" msgid "Save Changes" msgstr "" -#: plinth/modules/users/views.py:42 +#: plinth/modules/users/views.py:44 #, python-format msgid "User %(username)s created." msgstr "" -#: plinth/modules/users/views.py:76 +#: plinth/modules/users/views.py:80 #, python-format msgid "User %(username)s updated." msgstr "" -#: plinth/modules/users/views.py:77 +#: plinth/modules/users/views.py:81 msgid "Edit User" msgstr "" -#: plinth/modules/users/views.py:146 +#: plinth/modules/users/views.py:151 #, python-brace-format msgid "User {user} deleted." msgstr "" -#: plinth/modules/users/views.py:153 +#: plinth/modules/users/views.py:157 msgid "Deleting LDAP user failed." msgstr "" -#: plinth/modules/users/views.py:180 +#: plinth/modules/users/views.py:185 msgid "Change Password" msgstr "" -#: plinth/modules/users/views.py:181 +#: plinth/modules/users/views.py:186 msgid "Password changed successfully." msgstr "" @@ -7070,7 +7045,7 @@ msgstr "" msgid "Server deleted." msgstr "" -#: plinth/modules/wordpress/__init__.py:23 +#: plinth/modules/wordpress/__init__.py:19 msgid "" "WordPress is a popular way to create and manage websites and blogs. Content " "can be managed using a visual interface. Layout and functionality of the web " @@ -7079,7 +7054,7 @@ msgid "" "devices." msgstr "" -#: plinth/modules/wordpress/__init__.py:29 +#: plinth/modules/wordpress/__init__.py:25 #, python-brace-format msgid "" "You need to run WordPress setup by visiting the app before making the site " @@ -7088,26 +7063,26 @@ msgid "" "better URLs to your pages and posts." msgstr "" -#: plinth/modules/wordpress/__init__.py:34 +#: plinth/modules/wordpress/__init__.py:30 msgid "" "WordPress has its own user accounts. First administrator account is created " "during setup. Bookmark the admin page " "to reach administration interface in the future." msgstr "" -#: plinth/modules/wordpress/__init__.py:38 +#: plinth/modules/wordpress/__init__.py:34 msgid "" "After a major version upgrade, you need to manually run database upgrade " "from administrator interface. Additional plugins or themes may be installed " "and upgraded at your own risk." msgstr "" -#: plinth/modules/wordpress/__init__.py:56 +#: plinth/modules/wordpress/__init__.py:52 #: plinth/modules/wordpress/manifest.py:6 msgid "WordPress" msgstr "" -#: plinth/modules/wordpress/__init__.py:57 +#: plinth/modules/wordpress/__init__.py:53 msgid "Website and Blog" msgstr "" @@ -7121,7 +7096,7 @@ msgid "" "WordPress site or blog. Enable only after performing initial WordPress setup." msgstr "" -#: plinth/modules/zoph/__init__.py:26 +#: plinth/modules/zoph/__init__.py:22 #, python-brace-format msgid "" "Zoph manages your photo collection. Photos are stored on your {box_name}, " @@ -7134,7 +7109,7 @@ msgid "" "shared with others by sending a direct link." msgstr "" -#: plinth/modules/zoph/__init__.py:37 +#: plinth/modules/zoph/__init__.py:33 #, python-brace-format msgid "" "The {box_name} user who setup Zoph will also become the administrator in " @@ -7142,11 +7117,11 @@ msgid "" "in Zoph with the same user name." msgstr "" -#: plinth/modules/zoph/__init__.py:56 plinth/modules/zoph/manifest.py:6 +#: plinth/modules/zoph/__init__.py:52 plinth/modules/zoph/manifest.py:6 msgid "Zoph" msgstr "" -#: plinth/modules/zoph/__init__.py:57 +#: plinth/modules/zoph/__init__.py:53 msgid "Photo Organizer" msgstr "" @@ -7196,110 +7171,104 @@ msgstr "" msgid "Finished: {name}" msgstr "" -#: plinth/package.py:191 +#: plinth/package.py:188 #, python-brace-format msgid "Package {expression} is not available for install" msgstr "" -#: plinth/package.py:204 +#: plinth/package.py:201 #, python-brace-format msgid "Package {package_name} is the latest version ({latest_version})" msgstr "" -#: plinth/package.py:367 -#, fuzzy -#| msgid "Error During Backup" -msgid "Error running apt-get" -msgstr "備份時發生錯誤" - -#: plinth/package.py:389 +#: plinth/package.py:348 msgid "installing" msgstr "" -#: plinth/package.py:391 +#: plinth/package.py:350 msgid "downloading" msgstr "" -#: plinth/package.py:393 +#: plinth/package.py:352 msgid "media change" msgstr "" -#: plinth/package.py:395 +#: plinth/package.py:354 #, python-brace-format msgid "configuration file: {file}" msgstr "" -#: plinth/package.py:423 plinth/package.py:448 +#: plinth/package.py:382 plinth/package.py:407 msgid "Timeout waiting for package manager" msgstr "" -#: plinth/setup.py:40 +#: plinth/setup.py:41 msgid "Installing app" msgstr "" -#: plinth/setup.py:42 +#: plinth/setup.py:43 msgid "Updating app" msgstr "" -#: plinth/setup.py:68 +#: plinth/setup.py:69 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error installing app: {string} {details}" msgstr "安裝過程中遇到錯誤:{string}{details}" -#: plinth/setup.py:72 +#: plinth/setup.py:73 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error updating app: {string} {details}" msgstr "安裝過程中遇到錯誤:{string}{details}" -#: plinth/setup.py:78 +#: plinth/setup.py:79 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error installing app: {error}" msgstr "安裝應用遇到錯誤:{error}" -#: plinth/setup.py:81 +#: plinth/setup.py:82 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error updating app: {error}" msgstr "安裝應用遇到錯誤:{error}" -#: plinth/setup.py:85 +#: plinth/setup.py:86 #, fuzzy #| msgid "Application installed." msgid "App installed." msgstr "應用已完成安裝。" -#: plinth/setup.py:87 +#: plinth/setup.py:88 msgid "App updated" msgstr "" -#: plinth/setup.py:104 +#: plinth/setup.py:105 #, fuzzy #| msgid "Error installing application: {error}" msgid "Uninstalling app" msgstr "安裝應用遇到錯誤:{error}" -#: plinth/setup.py:122 +#: plinth/setup.py:123 #, fuzzy, python-brace-format #| msgid "Error installing application: {string} {details}" msgid "Error uninstalling app: {string} {details}" msgstr "安裝過程中遇到錯誤:{string}{details}" -#: plinth/setup.py:128 +#: plinth/setup.py:129 #, fuzzy, python-brace-format #| msgid "Error installing application: {error}" msgid "Error uninstalling app: {error}" msgstr "安裝應用遇到錯誤:{error}" -#: plinth/setup.py:131 +#: plinth/setup.py:132 #, fuzzy #| msgid "Application installed." msgid "App uninstalled." msgstr "應用已完成安裝。" -#: plinth/setup.py:451 +#: plinth/setup.py:452 msgid "Updating app packages" msgstr "" @@ -7350,53 +7319,54 @@ msgstr "" msgid "Service %(service_name)s is not running." msgstr "" -#: plinth/templates/base.html:30 -#, python-format -msgid "Core functionality and web interface for %(box_name)s" -msgstr "" - -#: plinth/templates/base.html:107 -msgid " Home" +#: plinth/templates/base.html:31 +msgid "" +"FreedomBox is a personal server designed for privacy and data ownership. It " +"is free software that lets you install and manage server apps with ease." msgstr "" #: plinth/templates/base.html:110 +msgid " Home" +msgstr "" + +#: plinth/templates/base.html:113 msgid "Home" msgstr "" -#: plinth/templates/base.html:115 +#: plinth/templates/base.html:118 msgid " Apps" msgstr "" -#: plinth/templates/base.html:119 +#: plinth/templates/base.html:122 msgid "Apps" msgstr "" -#: plinth/templates/base.html:124 +#: plinth/templates/base.html:127 msgid " System" msgstr "" -#: plinth/templates/base.html:128 +#: plinth/templates/base.html:131 msgid "System" msgstr "" -#: plinth/templates/base.html:163 plinth/templates/base.html:164 +#: plinth/templates/base.html:166 plinth/templates/base.html:167 msgid "Change password" msgstr "" -#: plinth/templates/base.html:177 plinth/templates/base.html:178 +#: plinth/templates/base.html:180 plinth/templates/base.html:181 msgid "Shut down" msgstr "" -#: plinth/templates/base.html:185 plinth/templates/base.html:186 -#: plinth/templates/base.html:213 plinth/templates/base.html:215 +#: plinth/templates/base.html:188 plinth/templates/base.html:189 +#: plinth/templates/base.html:216 plinth/templates/base.html:218 msgid "Log out" msgstr "" -#: plinth/templates/base.html:195 plinth/templates/base.html:198 +#: plinth/templates/base.html:198 plinth/templates/base.html:201 msgid "Select language" msgstr "" -#: plinth/templates/base.html:204 plinth/templates/base.html:206 +#: plinth/templates/base.html:207 plinth/templates/base.html:209 msgid "Log in" msgstr "" @@ -7660,6 +7630,17 @@ msgstr "" msgid "Gujarati" msgstr "" +#~ msgid "Enable DNSSEC" +#~ msgstr "啟用域名系統安全擴充 DNSSEC" + +#~ msgid "Enable Domain Name System Security Extensions" +#~ msgstr "啟用網域名稱系統安全擴充功能" + +#, fuzzy +#~| msgid "Error During Backup" +#~ msgid "Error running apt-get" +#~ msgstr "備份時發生錯誤" + #~ msgid "" #~ "Cockpit requires that you access it through a domain name. It will not " #~ "work when accessed using an IP address as part of the URL." diff --git a/plinth/modules/apache/__init__.py b/plinth/modules/apache/__init__.py index ca567090e..c0dffcae3 100644 --- a/plinth/modules/apache/__init__.py +++ b/plinth/modules/apache/__init__.py @@ -1,12 +1,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for Apache server. -""" +"""FreedomBox app for Apache server.""" + import os from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg from plinth.daemon import Daemon, RelatedDaemon @@ -15,13 +13,15 @@ from plinth.modules.letsencrypt.components import LetsEncrypt from plinth.package import Packages from plinth.utils import format_lazy, is_valid_user_name +from . import privileged + class ApacheApp(app_module.App): """FreedomBox app for Apache web server.""" app_id = 'apache' - _version = 10 + _version = 11 def __init__(self): """Create components for the app.""" @@ -60,9 +60,7 @@ class ApacheApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('apache', - ['setup', '--old-version', - str(old_version)]) + privileged.setup(old_version) self.enable() @@ -70,17 +68,17 @@ class ApacheApp(app_module.App): def uws_directory_of_user(user): - """Returns the directory of the given user's website.""" + """Return the directory of the given user's website.""" return '/home/{}/public_html'.format(user) def uws_url_of_user(user): - """Returns the url path of the given user's website.""" + """Return the url path of the given user's website.""" return '/~{}/'.format(user) def user_of_uws_directory(directory): - """Returns the user of a given user website directory.""" + """Return the user of a given user website directory.""" if directory.startswith('/home/'): pos_ini = 6 elif directory.startswith('home/'): @@ -97,7 +95,7 @@ def user_of_uws_directory(directory): def user_of_uws_url(url): - """Returns the user of a given user website url path.""" + """Return the user of a given user website url path.""" MISSING = -1 pos_ini = url.find('~') @@ -113,7 +111,7 @@ def user_of_uws_url(url): def uws_directory_of_url(url): - """Returns the directory of the user's website for the given url path. + """Return the directory of the user's website for the given url path. Note: It doesn't return the full OS file path to the url path! """ @@ -121,7 +119,7 @@ def uws_directory_of_url(url): def uws_url_of_directory(directory): - """Returns the url base path of the user's website for the given OS path. + """Return the url base path of the user's website for the given OS path. Note: It doesn't return the url path for the file! """ @@ -129,10 +127,10 @@ def uws_url_of_directory(directory): def get_users_with_website(): - """Returns a dictionary of users with actual website subdirectory.""" + """Return a dictionary of users with actual website subdirectory.""" def lst_sub_dirs(directory): - """Returns the list of subdirectories of the given directory.""" + """Return the list of subdirectories of the given directory.""" return [ name for name in os.listdir(directory) if os.path.isdir(os.path.join(directory, name)) diff --git a/plinth/modules/apache/components.py b/plinth/modules/apache/components.py index 7737dce5e..32449e045 100644 --- a/plinth/modules/apache/components.py +++ b/plinth/modules/apache/components.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -App component for other apps to use Apache configuration functionality. -""" +"""App component for other apps to use Apache configuration functionality.""" import re import subprocess @@ -9,7 +7,9 @@ import subprocess from django.utils.text import format_lazy from django.utils.translation import gettext_lazy -from plinth import action_utils, actions, app +from plinth import action_utils, app + +from . import privileged class Webserver(app.LeaderComponent): @@ -47,14 +47,11 @@ class Webserver(app.LeaderComponent): def enable(self): """Enable the Apache configuration.""" - actions.superuser_run( - 'apache', ['enable', '--name', self.web_name, '--kind', self.kind]) + privileged.enable(self.web_name, self.kind) def disable(self): """Disable the Apache configuration.""" - actions.superuser_run( - 'apache', - ['disable', '--name', self.web_name, '--kind', self.kind]) + privileged.disable(self.web_name, self.kind) def diagnose(self): """Check if the web path is accessible by clients. @@ -99,13 +96,11 @@ class Uwsgi(app.LeaderComponent): def enable(self): """Enable the uWSGI configuration.""" - actions.superuser_run('apache', - ['uwsgi-enable', '--name', self.uwsgi_name]) + privileged.uwsgi_enable(self.uwsgi_name) def disable(self): """Disable the uWSGI configuration.""" - actions.superuser_run('apache', - ['uwsgi-disable', '--name', self.uwsgi_name]) + privileged.uwsgi_disable(self.uwsgi_name) def is_running(self): """Return whether the uWSGI daemon is running with configuration.""" diff --git a/plinth/modules/apache/data/etc/fail2ban/jail.d/apache-auth-freedombox.conf b/plinth/modules/apache/data/etc/fail2ban/jail.d/apache-auth-freedombox.conf index 9e20fb6dc..25a0c8335 100644 --- a/plinth/modules/apache/data/etc/fail2ban/jail.d/apache-auth-freedombox.conf +++ b/plinth/modules/apache/data/etc/fail2ban/jail.d/apache-auth-freedombox.conf @@ -1,3 +1,6 @@ [apache-auth] enabled = true -backend = auto +# Tweak the filter regex to work with journal format. Use apache-error as the +# syslog facility +filter = apache-auth[logtype="journal",logging="syslog",_daemon="apache-error"] +journalmatch = SYSLOG_IDENTIFIER=apache-error diff --git a/actions/apache b/plinth/modules/apache/privileged.py old mode 100755 new mode 100644 similarity index 68% rename from actions/apache rename to plinth/modules/apache/privileged.py index 3a69648ff..812df5c1f --- a/actions/apache +++ b/plinth/modules/apache/privileged.py @@ -1,48 +1,13 @@ -#!/usr/bin/python3 -# -*- mode: python -*- # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Apache web server. -""" +"""Configure Apache web server.""" -import argparse import glob import os import re import subprocess from plinth import action_utils - - -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - subparser = subparsers.add_parser('setup', help='Setup for Apache') - subparser.add_argument( - '--old-version', type=int, required=True, - help='Earlier version of the app that is already setup.') - subparser = subparsers.add_parser( - 'enable', help='Enable a site/config/module in apache') - subparser.add_argument('--name', - help='Name of the site/config/module to enable') - subparser.add_argument('--kind', choices=['site', 'config', 'module']) - subparser = subparsers.add_parser( - 'disable', help='Disable a site/config/module in apache') - subparser.add_argument('--name', - help='Name of the site/config/module to disable') - subparser.add_argument('--kind', choices=['site', 'config', 'module']) - subparser = subparsers.add_parser( - 'uwsgi-enable', help='Enable a site/config/module in UWSGI') - subparser.add_argument('--name', - help='Name of the site/config/module to enable') - subparser = subparsers.add_parser( - 'uwsgi-disable', help='Disable a site/config/module in UWSGI') - subparser.add_argument('--name', - help='Name of the site/config/module to disable') - - subparsers.required = True - return parser.parse_args() +from plinth.actions import privileged def _get_sort_key_of_version(version): @@ -87,14 +52,15 @@ def _disable_mod_php(webserver): webserver.disable('php' + version, kind='module') -def subcommand_setup(arguments): +@privileged +def setup(old_version: int): """Setup Apache configuration.""" # Regenerate the snakeoil self-signed SSL certificate. This is so that # FreedomBox images don't all have the same certificate. When FreedomBox # package is installed via apt, don't regenerate. When upgrading to newer # version of Apache FreedomBox app and setting up for the first time don't # regenerate. - if action_utils.is_disk_image() and arguments.old_version == 0: + if action_utils.is_disk_image() and old_version == 0: subprocess.run([ 'make-ssl-cert', 'generate-default-snakeoil', '--force-overwrite' ], check=True) @@ -123,6 +89,9 @@ def subcommand_setup(arguments): webserver.enable('rewrite', kind='module') webserver.enable('macro', kind='module') + # Disable logging into files, use FreedomBox configured systemd logging + webserver.disable('other-vhosts-access-log', kind='config') + # Disable /server-status page to avoid leaking private info. webserver.disable('status', kind='module') @@ -178,34 +147,33 @@ def subcommand_setup(arguments): # TODO: Check that the (name, kind) is a managed by FreedomBox before # performing operation. -def subcommand_enable(arguments): +@privileged +def enable(name: str, kind: str): """Enable an Apache site/config/module.""" - action_utils.webserver_enable(arguments.name, arguments.kind) + _assert_kind(kind) + action_utils.webserver_enable(name, kind) -def subcommand_disable(arguments): +@privileged +def disable(name: str, kind: str): """Disable an Apache site/config/module.""" - action_utils.webserver_disable(arguments.name, arguments.kind) + _assert_kind(kind) + action_utils.webserver_disable(name, kind) -def subcommand_uwsgi_enable(arguments): +def _assert_kind(kind: str): + """Raise and exception if kind parameter has an unexpected value.""" + if kind not in ('site', 'config', 'module'): + raise ValueError('Invalid value for parameter kind') + + +@privileged +def uwsgi_enable(name: str): """Enable uWSGI configuration and reload.""" - action_utils.uwsgi_enable(arguments.name) + action_utils.uwsgi_enable(name) -def subcommand_uwsgi_disable(arguments): +@privileged +def uwsgi_disable(name: str): """Disable uWSGI configuration and reload.""" - action_utils.uwsgi_disable(arguments.name) - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() + action_utils.uwsgi_disable(name) diff --git a/plinth/modules/apache/tests/test_components.py b/plinth/modules/apache/tests/test_components.py index 7ceba4ca1..0eece880d 100644 --- a/plinth/modules/apache/tests/test_components.py +++ b/plinth/modules/apache/tests/test_components.py @@ -47,27 +47,22 @@ def test_webserver_is_enabled(webserver_is_enabled): webserver_is_enabled.assert_has_calls([call('test-config', kind='module')]) -@patch('plinth.actions.superuser_run') -def test_webserver_enable(superuser_run): +@patch('plinth.modules.apache.privileged.enable') +def test_webserver_enable(enable): """Test that enabling webserver configuration works.""" webserver = Webserver('test-webserver', 'test-config', kind='module') webserver.enable() - superuser_run.assert_has_calls([ - call('apache', ['enable', '--name', 'test-config', '--kind', 'module']) - ]) + enable.assert_has_calls([call('test-config', 'module')]) -@patch('plinth.actions.superuser_run') -def test_webserver_disable(superuser_run): +@patch('plinth.modules.apache.privileged.disable') +def test_webserver_disable(disable): """Test that disabling webserver configuration works.""" webserver = Webserver('test-webserver', 'test-config', kind='module') webserver.disable() - superuser_run.assert_has_calls([ - call('apache', - ['disable', '--name', 'test-config', '--kind', 'module']) - ]) + disable.assert_has_calls([call('test-config', 'module')]) @patch('plinth.modules.apache.components.diagnose_url') @@ -132,24 +127,22 @@ def test_uwsgi_is_enabled(uwsgi_is_enabled, service_is_enabled): assert not uwsgi.is_enabled() -@patch('plinth.actions.superuser_run') -def test_uwsgi_enable(superuser_run): +@patch('plinth.modules.apache.privileged.uwsgi_enable') +def test_uwsgi_enable(enable): """Test that enabling uwsgi configuration works.""" uwsgi = Uwsgi('test-uwsgi', 'test-config') uwsgi.enable() - superuser_run.assert_has_calls( - [call('apache', ['uwsgi-enable', '--name', 'test-config'])]) + enable.assert_has_calls([call('test-config')]) -@patch('plinth.actions.superuser_run') -def test_uwsgi_disable(superuser_run): +@patch('plinth.modules.apache.privileged.uwsgi_disable') +def test_uwsgi_disable(disable): """Test that disabling uwsgi configuration works.""" uwsgi = Uwsgi('test-uwsgi', 'test-config') uwsgi.disable() - superuser_run.assert_has_calls( - [call('apache', ['uwsgi-disable', '--name', 'test-config'])]) + disable.assert_has_calls([call('test-config')]) @patch('plinth.action_utils.service_is_running') diff --git a/plinth/modules/avahi/__init__.py b/plinth/modules/avahi/__init__.py index f06bbf271..420b4153b 100644 --- a/plinth/modules/avahi/__init__.py +++ b/plinth/modules/avahi/__init__.py @@ -1,11 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for service discovery. -""" +"""FreedomBox app for service discovery.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu from plinth.daemon import Daemon @@ -14,6 +11,7 @@ from plinth.modules.config import get_hostname from plinth.modules.firewall.components import Firewall from plinth.modules.names.components import DomainType from plinth.package import Packages +from plinth.privileged import service as service_privileged from plinth.signals import domain_added, domain_removed, post_hostname_change from plinth.utils import format_lazy @@ -90,7 +88,7 @@ class AvahiApp(app_module.App): # Reload avahi-daemon now that first-run does not reboot. After # performing FreedomBox Service (Plinth) package installation, new # Avahi files will be available and require restart. - actions.superuser_run('service', ['reload', 'avahi-daemon']) + service_privileged.reload('avahi-daemon') self.enable() diff --git a/plinth/modules/backups/__init__.py b/plinth/modules/backups/__init__.py index 0583af152..f4ab92f1b 100644 --- a/plinth/modules/backups/__init__.py +++ b/plinth/modules/backups/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to manage backup archives. -""" +"""FreedomBox app to manage backup archives.""" import json import logging @@ -14,12 +12,11 @@ from django.utils.text import get_valid_filename from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_noop -from plinth import actions from plinth import app as app_module from plinth import cfg, glib, menu from plinth.package import Packages -from . import api +from . import api, privileged logger = logging.getLogger(__name__) @@ -27,7 +24,6 @@ _description = [ _('Backups allows creating and managing backup archives.'), ] -MANIFESTS_FOLDER = '/var/lib/plinth/backups-manifests/' # session variable name that stores when a backup file should be deleted SESSION_PATH_VARIABLE = 'fbx-backups-upload-path' @@ -69,8 +65,7 @@ class BackupsApp(app_module.App): """Install and configure the app.""" super().setup(old_version) from . import repository - actions.superuser_run( - 'backups', ['setup', '--path', repository.RootBorgRepository.PATH]) + privileged.setup(repository.RootBorgRepository.PATH) self.enable() # First time setup or upgrading from older versions. @@ -79,11 +74,11 @@ class BackupsApp(app_module.App): def _backup_handler(packet, encryption_passphrase=None): - """Performs backup operation on packet.""" - if not os.path.exists(MANIFESTS_FOLDER): - os.makedirs(MANIFESTS_FOLDER) + """Perform backup operation on packet.""" + if not os.path.exists(privileged.MANIFESTS_FOLDER): + os.makedirs(privileged.MANIFESTS_FOLDER) - manifest_path = os.path.join(MANIFESTS_FOLDER, + manifest_path = os.path.join(privileged.MANIFESTS_FOLDER, get_valid_filename(packet.path) + '.json') manifests = { 'apps': [{ @@ -97,17 +92,10 @@ def _backup_handler(packet, encryption_passphrase=None): paths = packet.directories + packet.files paths.append(manifest_path) - arguments = ['create-archive', '--path', packet.path] - if packet.archive_comment: - arguments += ['--comment', packet.archive_comment] - arguments += ['--paths'] + paths - input_data = '' - if encryption_passphrase: - input_data = json.dumps( - {'encryption_passphrase': encryption_passphrase}) - - actions.superuser_run('backups', arguments, input=input_data.encode()) + privileged.create_archive(packet.path, paths, + comment=packet.archive_comment, + encryption_passphrase=encryption_passphrase) def backup_by_schedule(data): @@ -123,34 +111,16 @@ def backup_by_schedule(data): exception=exception) -def get_exported_archive_apps(path): - """Get list of apps included in exported archive file.""" - arguments = ['get-exported-archive-apps', '--path', path] - output = actions.superuser_run('backups', arguments) - return output.splitlines() - - def _restore_exported_archive_handler(packet, encryption_passphrase=None): """Perform restore operation on packet.""" - locations = {'directories': packet.directories, 'files': packet.files} - locations_data = json.dumps(locations) - actions.superuser_run('backups', - ['restore-exported-archive', '--path', packet.path], - input=locations_data.encode()) + privileged.restore_exported_archive(packet.path, packet.directories, + packet.files) def restore_archive_handler(packet, encryption_passphrase=None): """Perform restore operation on packet.""" - locations = { - 'directories': packet.directories, - 'files': packet.files, - 'encryption_passphrase': encryption_passphrase - } - locations_data = json.dumps(locations) - arguments = [ - 'restore-archive', '--path', packet.path, '--destination', '/' - ] - actions.superuser_run('backups', arguments, input=locations_data.encode()) + privileged.restore_archive(packet.path, '/', packet.directories, + packet.files, encryption_passphrase) def restore_from_upload(path, app_ids=None): diff --git a/plinth/modules/backups/api.py b/plinth/modules/backups/api.py index 336ad1948..6763b396e 100644 --- a/plinth/modules/backups/api.py +++ b/plinth/modules/backups/api.py @@ -12,9 +12,11 @@ TODO: import logging -from plinth import action_utils, actions +from plinth import action_utils from plinth import app as app_module from plinth import setup +from plinth.modules.apache import privileged as apache_privileged +from plinth.privileged import service as service_privileged from .components import BackupRestore @@ -317,12 +319,12 @@ class SystemServiceHandler(ServiceHandler): """Stop the service.""" self.was_running = action_utils.service_is_running(self.service) if self.was_running: - actions.superuser_run('service', ['stop', self.service]) + service_privileged.stop(self.service) def restart(self): """Restart the service if it was earlier running.""" if self.was_running: - actions.superuser_run('service', ['start', self.service]) + service_privileged.start(self.service) class ApacheServiceHandler(ServiceHandler): @@ -340,16 +342,12 @@ class ApacheServiceHandler(ServiceHandler): self.was_enabled = action_utils.webserver_is_enabled( self.web_name, kind=self.kind) if self.was_enabled: - actions.superuser_run( - 'apache', - ['disable', '--name', self.web_name, '--kind', self.kind]) + apache_privileged.disable(self.web_name, self.kind) def restart(self): """Restart the service if it was earlier running.""" if self.was_enabled: - actions.superuser_run( - 'apache', - ['enable', '--name', self.web_name, '--kind', self.kind]) + apache_privileged.enable(self.web_name, self.kind) def _shutdown_services(components): diff --git a/plinth/modules/backups/components.py b/plinth/modules/backups/components.py index 45165e856..6c668587b 100644 --- a/plinth/modules/backups/components.py +++ b/plinth/modules/backups/components.py @@ -1,12 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -App component for other apps to use backup/restore functionality. -""" +"""App component for other apps to use backup/restore functionality.""" import copy -import json -from plinth import actions, app +from plinth import app + +from . import privileged def _validate_directories_and_files(section): @@ -150,19 +149,14 @@ class BackupRestore(app.FollowerComponent): except Exception: pass - input_ = json.dumps(data).encode() - actions.superuser_run('backups', - ['dump-settings', '--app-id', self.app_id], - input=input_) + privileged.dump_settings(self.app_id, data) def _settings_restore_post(self): """Read from a file and restore keys to kvstore.""" if not self.settings: return - output = actions.superuser_run( - 'backups', ['load-settings', '--app-id', self.app_id]) - data = json.loads(output) + data = privileged.load_settings(self.app_id) from plinth import kvstore for key, value in data.items(): diff --git a/plinth/modules/backups/privileged.py b/plinth/modules/backups/privileged.py new file mode 100644 index 000000000..429eedc75 --- /dev/null +++ b/plinth/modules/backups/privileged.py @@ -0,0 +1,350 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure backups (with borg) and sshfs.""" + +import json +import os +import pathlib +import re +import subprocess +import tarfile +from typing import Optional, Union + +from plinth.actions import privileged +from plinth.utils import Version + +TIMEOUT = 30 +BACKUPS_DATA_PATH = pathlib.Path('/var/lib/plinth/backups-data/') +MANIFESTS_FOLDER = '/var/lib/plinth/backups-manifests/' + + +class AlreadyMountedError(Exception): + """Exception raised when mount point is already mounted.""" + + +@privileged +def mount(mountpoint: str, remote_path: str, ssh_keyfile: Optional[str] = None, + password: Optional[str] = None, + user_known_hosts_file: str = '/dev/null'): + """Mount a remote ssh path via sshfs.""" + try: + _validate_mountpoint(mountpoint) + except AlreadyMountedError: + return + + kwargs = {} + # the shell would expand ~/ to the local home directory + remote_path = remote_path.replace('~/', '').replace('~', '') + # 'reconnect', 'ServerAliveInternal' and 'ServerAliveCountMax' allow the + # client (FreedomBox) to keep control of the SSH connection even when the + # SSH server misbehaves. Without these options, other commands such as + # '/usr/share/plinth/actions/actions storage usage_info --no-args', 'df', + # '/usr/share/plinth/actions/actions sshfs is_mounted --no-args', or + # 'mountpoint' might block indefinitely (even when manually invoked from + # the command line). This situation has some lateral effects, causing major + # system instability in the course of ~11 days, and leaving the system in + # such state that the only solution is a reboot. + cmd = [ + 'sshfs', remote_path, mountpoint, '-o', + f'UserKnownHostsFile={user_known_hosts_file}', '-o', + 'StrictHostKeyChecking=yes', '-o', 'reconnect', '-o', + 'ServerAliveInterval=15', '-o', 'ServerAliveCountMax=3' + ] + if ssh_keyfile: + cmd += ['-o', 'IdentityFile=' + ssh_keyfile] + else: + if not password: + raise ValueError('mount requires either a password or ssh_keyfile') + cmd += ['-o', 'password_stdin'] + kwargs['input'] = password.encode() + + subprocess.run(cmd, check=True, timeout=TIMEOUT, **kwargs) + + +@privileged +def umount(mountpoint: str): + """Unmount a mountpoint.""" + subprocess.run(['umount', mountpoint], check=True) + + +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) + if os.listdir(mountpoint) or not os.path.isdir(mountpoint): + raise ValueError('Mountpoint %s is not an empty directory' % + mountpoint) + else: + os.makedirs(mountpoint) + + +def _is_mounted(mountpoint): + """Return boolean whether a local directory is a mountpoint.""" + cmd = ['mountpoint', '-q', mountpoint] + # mountpoint exits with status non-zero if it didn't find a mountpoint + try: + subprocess.run(cmd, check=True) + return True + except subprocess.CalledProcessError: + return False + + +@privileged +def is_mounted(mount_point: str) -> bool: + """Return whether a path is already mounted.""" + return _is_mounted(mount_point) + + +@privileged +def setup(path: str): + """Create repository if it does not already exist.""" + try: + _run(['borg', 'info', path], check=True) + except subprocess.CalledProcessError: + parent = os.path.dirname(path) + if not os.path.exists(parent): + os.makedirs(parent) + + _init_repository(path, encryption='none') + + +def _init_repository(path: str, encryption: str, + encryption_passphrase: Optional[str] = None): + """Initialize a local or remote borg repository.""" + if encryption != 'none': + if not encryption_passphrase: + raise ValueError('No encryption passphrase provided') + + cmd = ['borg', 'init', '--encryption', encryption, path] + _run(cmd, encryption_passphrase) + + +@privileged +def init(path: str, encryption: str, + encryption_passphrase: Optional[str] = None): + """Initialize the borg repository.""" + _init_repository(path, encryption, encryption_passphrase) + + +@privileged +def info(path: str, encryption_passphrase: Optional[str] = None) -> dict: + """Show repository information.""" + process = _run(['borg', 'info', '--json', path], encryption_passphrase, + stdout=subprocess.PIPE) + return json.loads(process.stdout.decode()) + + +@privileged +def list_repo(path: str, encryption_passphrase: Optional[str] = None) -> dict: + """List repository contents.""" + process = _run(['borg', 'list', '--json', '--format="{comment}"', path], + encryption_passphrase, stdout=subprocess.PIPE) + return json.loads(process.stdout.decode()) + + +def _get_borg_version(): + """Return the version of borgbackup.""" + process = _run(['borg', '--version'], stdout=subprocess.PIPE) + return process.stdout.decode().split()[1] # Example: "borg 1.1.9" + + +@privileged +def create_archive(path: str, paths: list[str], comment: Optional[str] = None, + encryption_passphrase: Optional[str] = None): + """Create archive.""" + existing_paths = filter(os.path.exists, paths) + command = ['borg', 'create', '--json'] + if comment: + if Version(_get_borg_version()) < Version('1.1.10'): + # Undo any placeholder escape sequences in comments as this version + # of borg does not support placeholders. XXX: Drop this code when + # support for borg < 1.1.10 is dropped. + comment = comment.replace('{{', '{').replace('}}', '}') + + command += ['--comment', comment] + + command += [path] + list(existing_paths) + _run(command, encryption_passphrase) + + +@privileged +def delete_archive(path: str, encryption_passphrase: Optional[str] = None): + """Delete archive.""" + _run(['borg', 'delete', path], encryption_passphrase) + + +def _extract(archive_path, destination, encryption_passphrase, locations=None): + """Extract archive contents.""" + prev_dir = os.getcwd() + borg_call = ['borg', 'extract', archive_path] + # do not extract any files when we get an empty locations list + if locations is not None: + borg_call.extend(locations) + + try: + os.chdir(os.path.expanduser(destination)) + # TODO: with python 3.7 use subprocess.run with the 'capture_output' + # argument + process = _run(borg_call, encryption_passphrase, check=False, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if process.returncode != 0: + error = process.stderr.decode() + # Don't fail on the borg error when no files were matched + if "never matched" not in error: + raise subprocess.CalledProcessError(process.returncode, + process.args) + finally: + os.chdir(prev_dir) + + +@privileged +def export_tar(path: str, encryption_passphrase: Optional[str] = None): + """Export archive contents as tar stream on stdout.""" + _run(['borg', 'export-tar', path, '-', '--tar-filter=gzip'], + encryption_passphrase) + + +def _read_archive_file(archive, filepath, encryption_passphrase): + """Read the content of a file inside an archive.""" + borg_call = ['borg', 'extract', archive, filepath, '--stdout'] + return _run(borg_call, encryption_passphrase, + stdout=subprocess.PIPE).stdout.decode() + + +@privileged +def get_archive_apps(path: str, + encryption_passphrase: Optional[str] = None) -> list[str]: + """Get list of apps included in archive.""" + manifest_folder = os.path.relpath(MANIFESTS_FOLDER, '/') + borg_call = [ + 'borg', 'list', path, manifest_folder, '--format', '{path}{NEWLINE}' + ] + try: + borg_process = _run(borg_call, encryption_passphrase, + stdout=subprocess.PIPE) + manifest_path = borg_process.stdout.decode().strip() + except subprocess.CalledProcessError: + raise RuntimeError('Borg exited unsuccessfully') + + manifest = None + if manifest_path: + manifest_data = _read_archive_file(path, manifest_path, + encryption_passphrase) + manifest = json.loads(manifest_data) + + archive_apps = [] + if manifest: + for app in _get_apps_of_manifest(manifest): + archive_apps.append(app['name']) + + return archive_apps + + +def _get_apps_of_manifest(manifest): + """Get apps of a manifest. + + Supports both dict format as well as list format of plinth <=0.42 + + """ + if isinstance(manifest, list): + apps = manifest + elif isinstance(manifest, dict) and 'apps' in manifest: + apps = manifest['apps'] + else: + raise RuntimeError('Unknown manifest format') + + return apps + + +@privileged +def get_exported_archive_apps(path: str) -> list[str]: + """Get list of apps included in an exported archive file.""" + manifest = None + with tarfile.open(path) as tar_handle: + filenames = tar_handle.getnames() + for name in filenames: + if 'var/lib/plinth/backups-manifests/' in name \ + and name.endswith('.json'): + manifest_data = tar_handle.extractfile(name).read() + manifest = json.loads(manifest_data) + break + + app_names = [] + if manifest: + for app in _get_apps_of_manifest(manifest): + app_names.append(app['name']) + + return app_names + + +@privileged +def restore_archive(archive_path: str, destination: str, + directories: list[str], files: list[str], + encryption_passphrase: Optional[str] = None): + """Restore files from an archive.""" + locations_all = directories + files + locations_all = [ + os.path.relpath(location, '/') for location in locations_all + ] + _extract(archive_path, destination, encryption_passphrase, + locations=locations_all) + + +@privileged +def restore_exported_archive(path: str, directories: list[str], + files: list[str]): + """Restore files from an exported archive.""" + with tarfile.open(path) as tar_handle: + for member in tar_handle.getmembers(): + path = '/' + member.name + if path in files: + tar_handle.extract(member, '/') + else: + for directory in directories: + if path.startswith(directory): + tar_handle.extract(member, '/') + break + + +def _assert_app_id(app_id): + """Check that app ID is correct.""" + if not re.fullmatch(r'[a-z0-9_]+', app_id): + raise Exception('Invalid App ID') + + +@privileged +def dump_settings(app_id: str, settings: dict[str, Union[int, float, bool, + str]]): + """Dump an app's settings to a JSON file.""" + _assert_app_id(app_id) + BACKUPS_DATA_PATH.mkdir(exist_ok=True) + settings_path = BACKUPS_DATA_PATH / f'{app_id}-settings.json' + settings_path.write_text(json.dumps(settings)) + + +@privileged +def load_settings(app_id: str) -> dict[str, Union[int, float, bool, str]]: + """Load an app's settings from a JSON file.""" + _assert_app_id(app_id) + settings_path = BACKUPS_DATA_PATH / f'{app_id}-settings.json' + try: + return json.loads(settings_path.read_text()) + except FileNotFoundError: + return {} + + +def _get_env(encryption_passphrase: Optional[str] = None): + """Create encryption and ssh kwargs out of given arguments.""" + env = dict(os.environ, BORG_RELOCATED_REPO_ACCESS_IS_OK='yes', + LANG='C.UTF-8') + # Always provide BORG_PASSPHRASE (also if empty) so borg does not get stuck + # while asking for a passphrase. + env['BORG_PASSPHRASE'] = encryption_passphrase or '' + return env + + +def _run(cmd, encryption_passphrase=None, check=True, **kwargs): + """Wrap the command with extra encryption passphrase handling.""" + env = _get_env(encryption_passphrase) + return subprocess.run(cmd, check=check, env=env, **kwargs) diff --git a/plinth/modules/backups/repository.py b/plinth/modules/backups/repository.py index 25aca4aef..9fc7101f3 100644 --- a/plinth/modules/backups/repository.py +++ b/plinth/modules/backups/repository.py @@ -1,12 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Remote and local Borg backup repositories -""" +"""Remote and local Borg backup repositories.""" import abc import contextlib import io -import json import logging import os import re @@ -15,11 +12,10 @@ from uuid import uuid1 import paramiko from django.utils.translation import gettext_lazy as _ -from plinth import actions, cfg -from plinth.errors import ActionError +from plinth import cfg from plinth.utils import format_lazy -from . import (_backup_handler, api, errors, get_known_hosts_path, +from . import (_backup_handler, api, errors, get_known_hosts_path, privileged, restore_archive_handler, split_path, store) from .schedule import Schedule @@ -139,8 +135,10 @@ class BaseBorgRepository(abc.ABC): def get_info(self): """Return Borg information about a repository.""" - output = self.run(['info', '--path', self.borg_path]) - output = json.loads(output) + with self._handle_errors(): + output = privileged.info(self.borg_path, + self._get_encryption_passpharse()) + if output['encryption']['mode'] == 'none' and \ self._get_encryption_data(): raise errors.BorgUnencryptedRepository( @@ -149,7 +147,7 @@ class BaseBorgRepository(abc.ABC): return output def get_view_content(self): - """Get archives with additional information as needed by the view""" + """Get archives with additional information as needed by the view.""" repository = { 'uuid': self.uuid, 'name': self.name, @@ -162,7 +160,7 @@ class BaseBorgRepository(abc.ABC): repository['mounted'] = self.is_mounted if repository['mounted']: repository['archives'] = self.list_archives() - except (errors.BorgError, ActionError) as err: + except (errors.BorgError, Exception) as err: repository['error'] = str(err) return repository @@ -172,8 +170,9 @@ class BaseBorgRepository(abc.ABC): def list_archives(self): """Return list of archives in this repository.""" - output = self.run(['list-repo', '--path', self.borg_path]) - archives = json.loads(output)['archives'] + with self._handle_errors(): + archives = privileged.list_repo( + self.borg_path, self._get_encryption_passpharse())['archives'] return sorted(archives, key=lambda archive: archive['start'], reverse=True) @@ -188,7 +187,9 @@ class BaseBorgRepository(abc.ABC): def delete_archive(self, archive_name): """Delete an archive with given name from this repository.""" archive_path = self._get_archive_path(archive_name) - self.run(['delete-archive', '--path', archive_path]) + with self._handle_errors(): + privileged.delete_archive(archive_path, + self._get_encryption_passpharse()) def initialize(self): """Initialize / create a borg repository.""" @@ -198,8 +199,9 @@ class BaseBorgRepository(abc.ABC): encryption = 'repokey' try: - self.run( - ['init', '--path', self.borg_path, '--encryption', encryption]) + with self._handle_errors(): + privileged.init(self.borg_path, encryption, + self._get_encryption_passpharse()) except errors.BorgRepositoryExists: pass @@ -213,25 +215,21 @@ class BaseBorgRepository(abc.ABC): return {} - def _run(self, cmd, arguments, superuser=True, **kwargs): - """Run a backups or sshfs action script command.""" + @contextlib.contextmanager + def _handle_errors(self): + """Parse exceptions into more specific ones.""" try: - if superuser: - return actions.superuser_run(cmd, arguments, **kwargs) + yield + except Exception as exception: + self.reraise_known_error(exception) - return actions.run(cmd, arguments, **kwargs) - except ActionError as err: - self.reraise_known_error(err) - - def run(self, arguments, superuser=True): - """Add credentials and run a backups action script command.""" + def _get_encryption_passpharse(self): + """Return encryption passphrase or raise an exception.""" for key in self.credentials.keys(): if key not in self.known_credentials: raise ValueError('Unknown credentials entry: %s' % key) - input_data = json.dumps(self._get_encryption_data()) - return self._run('backups', arguments, superuser=superuser, - input=input_data.encode()) + return self.credentials.get('encryption_passphrase', None) def get_download_stream(self, archive_name): """Return an stream of .tar.gz binary data for a backup archive.""" @@ -258,11 +256,16 @@ class BaseBorgRepository(abc.ABC): return chunk - args = ['export-tar', '--path', self._get_archive_path(archive_name)] - input_data = json.dumps(self._get_encryption_data()) - proc = self._run('backups', args, run_in_background=True) - proc.stdin.write(input_data.encode()) + with self._handle_errors(): + proc, read_fd, input_ = privileged.export_tar( + self._get_archive_path(archive_name), + self._get_encryption_passpharse(), _raw_output=True) + + os.close(read_fd) # Don't use the pipe for communication, just stdout + proc.stdin.write(input_) proc.stdin.close() + proc.stderr.close() # writing to stderr in child will cause SIGPIPE + return BufferedReader(proc.stdout) def _get_archive_path(self, archive_name): @@ -272,7 +275,7 @@ class BaseBorgRepository(abc.ABC): @staticmethod def reraise_known_error(err): """Look whether the caught error is known and reraise it accordingly""" - caught_error = str(err) + caught_error = str((err, err.args)) for known_error in KNOWN_ERRORS: for error in known_error['errors']: if re.search(error, caught_error): @@ -291,8 +294,9 @@ class BaseBorgRepository(abc.ABC): def get_archive_apps(self, archive_name): """Get list of apps included in an archive.""" archive_path = self._get_archive_path(archive_name) - output = self.run(['get-archive-apps', '--path', archive_path]) - return output.splitlines() + with self._handle_errors(): + return privileged.get_archive_apps( + archive_path, self._get_encryption_passpharse()) def restore_archive(self, archive_name, app_ids=None): """Restore an archive from this repository to the system.""" @@ -418,9 +422,8 @@ class SshBorgRepository(BaseBorgRepository): @property def is_mounted(self): """Return whether remote path is mounted locally.""" - output = self._run('sshfs', - ['is-mounted', '--mountpoint', self._mountpoint]) - return json.loads(output) + with self._handle_errors(): + return privileged.is_mounted(self._mountpoint) def initialize(self): """Initialize the repository after mounting the target directory.""" @@ -432,22 +435,27 @@ class SshBorgRepository(BaseBorgRepository): """Mount the remote path locally using sshfs.""" if self.is_mounted: return + known_hosts_path = get_known_hosts_path() - arguments = [ - 'mount', '--mountpoint', self._mountpoint, '--path', self._path, - '--user-known-hosts-file', - str(known_hosts_path) - ] - arguments, kwargs = self._append_sshfs_arguments( - arguments, self.credentials) - self._run('sshfs', arguments, **kwargs) + kwargs = {'user_known_hosts_file': str(known_hosts_path)} + if 'ssh_password' in self.credentials and self.credentials[ + 'ssh_password']: + kwargs['password'] = self.credentials['ssh_password'] + + if 'ssh_keyfile' in self.credentials and self.credentials[ + 'ssh_keyfile']: + kwargs['ssh_keyfile'] = self.credentials['ssh_keyfile'] + + with self._handle_errors(): + privileged.mount(self._mountpoint, self._path, **kwargs) def umount(self): """Unmount the remote path that was mounted locally using sshfs.""" if not self.is_mounted: return - self._run('sshfs', ['umount', '--mountpoint', self._mountpoint]) + with self._handle_errors(): + privileged.umount(self._mountpoint) def _umount_ignore_errors(self): """Run unmount operation and ignore any exceptions thrown.""" @@ -457,33 +465,20 @@ class SshBorgRepository(BaseBorgRepository): logger.warning('Unable to unmount repository', exc_info=exception) def remove(self): - """Remove a repository from the kvstore and delete its mountpoint""" + """Remove a repository from the kvstore and delete its mountpoint.""" self.umount() store.delete(self.uuid) try: if os.path.exists(self._mountpoint): try: self.umount() - except ActionError: + except Exception: pass if not os.listdir(self._mountpoint): os.rmdir(self._mountpoint) except Exception as err: logger.error(err) - @staticmethod - def _append_sshfs_arguments(arguments, credentials): - """Add credentials to a run command and kwargs""" - kwargs = {} - - if 'ssh_password' in credentials and credentials['ssh_password']: - kwargs['input'] = credentials['ssh_password'].encode() - - if 'ssh_keyfile' in credentials and credentials['ssh_keyfile']: - arguments += ['--ssh-keyfile', credentials['ssh_keyfile']] - - return (arguments, kwargs) - def _ensure_remote_directory(self): """Create remote SSH directory if it does not exist.""" username, hostname, dir_path = split_path(self.path) diff --git a/plinth/modules/backups/tests/test_api.py b/plinth/modules/backups/tests/test_api.py index cdcd6fa7d..484de1c70 100644 --- a/plinth/modules/backups/tests/test_api.py +++ b/plinth/modules/backups/tests/test_api.py @@ -157,8 +157,10 @@ class TestBackupProcesses: @staticmethod @patch('plinth.action_utils.webserver_is_enabled') @patch('plinth.action_utils.service_is_running') - @patch('plinth.actions.superuser_run') - def test__shutdown_services(run, service_is_running, webserver_is_enabled): + @patch('plinth.privileged.service.stop') + @patch('plinth.modules.apache.privileged.disable') + def test__shutdown_services(apache_disable, service_stop, + service_is_running, webserver_is_enabled): """Test that services are stopped in correct order.""" components = [_get_backup_component('a'), _get_backup_component('b')] service_is_running.return_value = True @@ -182,17 +184,13 @@ class TestBackupProcesses: [call('b', kind='site'), call('a', kind='site')]) - calls = [ - call('apache', ['disable', '--name', 'b', '--kind', 'site']), - call('service', ['stop', 'b']), - call('apache', ['disable', '--name', 'a', '--kind', 'site']), - call('service', ['stop', 'a']) - ] - run.assert_has_calls(calls) + apache_disable.assert_has_calls([call('b', 'site'), call('a', 'site')]) + service_stop.assert_has_calls([call('b'), call('a')]) @staticmethod - @patch('plinth.actions.superuser_run') - def test__restore_services(run): + @patch('plinth.privileged.service.start') + @patch('plinth.modules.apache.privileged.enable') + def test__restore_services(apache_enable, service_start): """Test that services are restored in correct order.""" original_state = [ api.SystemServiceHandler(None, 'a-service'), @@ -211,11 +209,8 @@ class TestBackupProcesses: original_state[2].was_enabled = True original_state[3].was_enabled = False api._restore_services(original_state) - calls = [ - call('service', ['start', 'a-service']), - call('apache', ['enable', '--name', 'c-service', '--kind', 'site']) - ] - run.assert_has_calls(calls) + service_start.assert_has_calls([call('a-service')]) + apache_enable.assert_has_calls([call('c-service', 'site')]) @staticmethod def test__run_operation(): diff --git a/plinth/modules/backups/tests/test_backups.py b/plinth/modules/backups/tests/test_backups.py index d8007cef9..517a63dd1 100644 --- a/plinth/modules/backups/tests/test_backups.py +++ b/plinth/modules/backups/tests/test_backups.py @@ -3,7 +3,6 @@ Test the backups action script. """ -import json import os import pathlib import subprocess @@ -11,8 +10,8 @@ import uuid import pytest -from plinth import actions from plinth.modules import backups +from plinth.modules.backups import privileged from plinth.modules.backups.repository import BorgRepository, SshBorgRepository from plinth.tests import config as test_config @@ -94,11 +93,8 @@ def test_create_export_delete_archive(data_directory, backup_directory): repository = BorgRepository(str(path)) repository.initialize() archive_path = "::".join([str(path), archive_name]) - actions.superuser_run('backups', [ - 'create-archive', '--path', archive_path, '--comment', archive_comment, - '--paths', - str(data_directory) - ]) + privileged.create_archive(archive_path, [str(data_directory)], + archive_comment) archive = repository.list_archives()[0] assert archive['name'] == archive_name @@ -118,28 +114,18 @@ def test_remote_backup_actions(): """ credentials = _get_credentials(add_encryption_passphrase=True) path = os.path.join(test_config.backups_ssh_path, str(uuid.uuid1())) - arguments = ['init', '--path', path, '--encryption', 'repokey'] - arguments, kwargs = _append_borg_arguments(arguments, credentials) - actions.superuser_run('backups', arguments, **kwargs) + privileged.init(path, 'repokey', **_get_borg_arguments(credentials)) - arguments = ['info', '--path', path] - arguments, kwargs = _append_borg_arguments(arguments, credentials) - info = actions.superuser_run('backups', arguments, **kwargs) - info = json.loads(info) + info = privileged.info(path, **_get_borg_arguments(credentials)) assert info['encryption']['mode'] == 'repokey' -def _append_borg_arguments(arguments, credentials): - """Append run arguments for running borg directly""" - kwargs = {} - passphrase = credentials.get('encryption_passphrase', None) - if passphrase: - kwargs['input'] = json.dumps({'encryption_passphrase': passphrase}) - - if 'ssh_keyfile' in credentials and credentials['ssh_keyfile']: - arguments += ['--ssh-keyfile', credentials['ssh_keyfile']] - - return (arguments, kwargs) +def _get_borg_arguments(credentials): + """Get credential arguments for running borg privileged actions.""" + return { + 'passphrase': credentials.get('encryption_passphrase', None), + 'ssh_keyfile': credentials.get('ssh_keyfile') + } @pytest.mark.usefixtures('needs_ssh_config') diff --git a/plinth/modules/backups/tests/test_components.py b/plinth/modules/backups/tests/test_components.py index 29a88d91d..e5cc39b96 100644 --- a/plinth/modules/backups/tests/test_components.py +++ b/plinth/modules/backups/tests/test_components.py @@ -3,7 +3,6 @@ Test the App components provides by backups app. """ -import json from unittest.mock import call, patch import pytest @@ -235,8 +234,8 @@ def test_backup_restore_hooks(backup_restore): @pytest.mark.django_db -@patch('plinth.actions.superuser_run') -def test_backup_restore_backup_pre(run, backup_restore): +@patch('plinth.modules.backups.privileged.dump_settings') +def test_backup_restore_backup_pre(dump_settings, backup_restore): """Test running backup-pre hook.""" packet = None kvstore.set('setting-1', 'value-1') @@ -244,32 +243,27 @@ def test_backup_restore_backup_pre(run, backup_restore): component = BackupRestore('test-backup-restore') component.backup_pre(packet) - run.assert_has_calls([]) + dump_settings.assert_has_calls([]) backup_restore.backup_pre(packet) - input_ = {'setting-1': 'value-1'} - run.assert_has_calls([ - call('backups', ['dump-settings', '--app-id', 'testapp'], - input=json.dumps(input_).encode()) - ]) + dump_settings.assert_has_calls([call('testapp', {'setting-1': 'value-1'})]) @pytest.mark.django_db -@patch('plinth.actions.superuser_run') -def test_backup_restore_restore_post(run, backup_restore): +@patch('plinth.modules.backups.privileged.load_settings') +def test_backup_restore_restore_post(load_settings, backup_restore): """Test running restore-post hook.""" packet = None backup_restore.app_id = 'testapp' component = BackupRestore('test-backup-restore') component.restore_post(packet) - run.assert_has_calls([]) + load_settings.assert_has_calls([]) output = {'setting-1': 'value-1'} - run.return_value = json.dumps(output) + load_settings.return_value = output backup_restore.restore_post(packet) - run.assert_has_calls( - [call('backups', ['load-settings', '--app-id', 'testapp'])]) + load_settings.assert_has_calls([call('testapp')]) assert kvstore.get('setting-1') == 'value-1' with pytest.raises(Exception): diff --git a/plinth/modules/backups/views.py b/plinth/modules/backups/views.py index d613e7b18..fdadea719 100644 --- a/plinth/modules/backups/views.py +++ b/plinth/modules/backups/views.py @@ -25,7 +25,7 @@ from plinth.modules import backups, storage from plinth.views import AppView from . import (SESSION_PATH_VARIABLE, api, forms, get_known_hosts_path, - is_ssh_hostkey_verified) + is_ssh_hostkey_verified, privileged) from .decorators import delete_tmp_backup_file from .repository import (BorgRepository, SshBorgRepository, get_instance, get_repositories) @@ -238,7 +238,7 @@ class RestoreFromUploadView(BaseRestoreView): def _get_included_apps(self): """Save some data used to instantiate the form.""" path = self.request.session.get(SESSION_PATH_VARIABLE) - return backups.get_exported_archive_apps(path) + return privileged.get_exported_archive_apps(path) def form_valid(self, form): """Restore files from the archive on valid form submission.""" diff --git a/plinth/modules/bepasty/__init__.py b/plinth/modules/bepasty/__init__.py index e97e8caf9..d02b8139b 100644 --- a/plinth/modules/bepasty/__init__.py +++ b/plinth/modules/bepasty/__init__.py @@ -1,13 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for bepasty. -""" - -import json +"""FreedomBox app for bepasty.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.modules.apache.components import Uwsgi, Webserver @@ -15,7 +10,7 @@ from plinth.modules.backups.components import BackupRestore from plinth.modules.firewall.components import Firewall from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('bepasty is a web application that allows large files to be uploaded ' @@ -97,38 +92,10 @@ class BepastyApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('bepasty', - ['setup', '--domain-name', 'freedombox.local']) + privileged.setup('freedombox.local') self.enable() - if old_version == 1 and not get_configuration().get( + if old_version == 1 and not privileged.get_configuration().get( 'DEFAULT_PERMISSIONS'): # Upgrade to a better default only if user hasn't changed the # value. - set_default_permissions('read') - - -def get_configuration(): - """Get a full configuration including passwords and defaults.""" - output = actions.superuser_run('bepasty', ['get-configuration']) - return json.loads(output) - - -def add_password(permissions, comment=None): - """Generate a password with given permissions.""" - command = ['add-password', '--permissions'] + permissions - if comment: - command += ['--comment', comment] - - actions.superuser_run('bepasty', command) - - -def remove_password(password): - """Remove a password and its permissions.""" - actions.superuser_run('bepasty', ['remove-password'], - input=password.encode()) - - -def set_default_permissions(permissions): - """Set default permissions.""" - perm = permissions.split() - actions.superuser_run('bepasty', ['set-default', '--permissions'] + perm) + privileged.set_default(['read']) diff --git a/actions/bepasty b/plinth/modules/bepasty/privileged.py old mode 100755 new mode 100644 similarity index 64% rename from actions/bepasty rename to plinth/modules/bepasty/privileged.py index b8bf179a0..4c28ec803 --- a/actions/bepasty +++ b/plinth/modules/bepasty/privileged.py @@ -1,10 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for bepasty. -""" +"""Configuration helper for bepasty.""" -import argparse import collections import grp import json @@ -15,11 +11,12 @@ import secrets import shutil import string import subprocess -import sys +from typing import Optional import augeas from plinth import action_utils +from plinth.actions import privileged from plinth.modules import bepasty DATA_DIR = '/var/lib/bepasty' @@ -29,42 +26,6 @@ PASSWORD_LENGTH = 20 CONF_FILE = pathlib.Path('/etc/bepasty-freedombox.conf') -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - setup = subparsers.add_parser( - 'setup', help='Perform post-installation operations for bepasty') - setup.add_argument('--domain-name', required=True, - help='The domain name that will be used by bepasty') - - subparsers.add_parser('get-configuration', help='Get all configuration') - - add_password = subparsers.add_parser( - 'add-password', help='Generate a password with given permissions') - add_password.add_argument( - '--permissions', nargs='+', - help='Any number of permissions from the set: {}'.format(', '.join( - bepasty.PERMISSIONS.keys()))) - add_password.add_argument( - '--comment', required=False, - help='A comment for the password and its permissions') - - subparsers.add_parser('remove-password', - help='Remove a password and its permissions') - - set_default = subparsers.add_parser('set-default', - help='Set default permissions') - set_default.add_argument( - '--permissions', nargs='*', - help='Any number of permissions from the set: {}'.format(', '.join( - bepasty.PERMISSIONS.keys()))) - - subparsers.required = True - return parser.parse_args() - - def _augeas_load(): """Initialize Augeas.""" aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + @@ -104,7 +65,8 @@ def conf_file_write(conf): aug.save() -def subcommand_setup(arguments): +@privileged +def setup(domain_name: str): """Post installation actions for bepasty.""" # Create bepasty group if needed. try: @@ -135,7 +97,7 @@ def subcommand_setup(arguments): 'the original configuration format is supported. Each line ' 'should be in KEY = VALUE format. VALUE must be a JSON ' 'encoded string.', - 'SITENAME': arguments.domain_name, + 'SITENAME': domain_name, 'STORAGE_FILESYSTEM_DIRECTORY': '/var/lib/bepasty', 'SECRET_KEY': secrets.token_hex(64), 'PERMISSIONS': { @@ -155,29 +117,30 @@ def subcommand_setup(arguments): shutil.chown(CONF_FILE, user='bepasty', group='bepasty') -def subcommand_get_configuration(_): +@privileged +def get_configuration() -> dict[str, object]: """Get default permissions, passwords, permissions and comments.""" - conf = conf_file_read() - print(json.dumps(conf)) + return conf_file_read() -def subcommand_add_password(arguments): +@privileged +def add_password(permissions: list[str], comment: Optional[str] = None): """Generate a password with given permissions.""" conf = conf_file_read() - permissions = _format_permissions(arguments.permissions) + permissions = _format_permissions(permissions) password = _generate_password() conf['PERMISSIONS'][password] = permissions - if arguments.comment: - conf['PERMISSION_COMMENTS'][password] = arguments.comment + if comment: + conf['PERMISSION_COMMENTS'][password] = comment conf_file_write(conf) action_utils.service_try_restart('uwsgi') -def subcommand_remove_password(_arguments): +@privileged +def remove_password(password: str): """Remove a password and its permissions.""" conf = conf_file_read() - password = ''.join(sys.stdin) if password in conf['PERMISSIONS']: del conf['PERMISSIONS'][password] @@ -187,9 +150,10 @@ def subcommand_remove_password(_arguments): action_utils.service_try_restart('uwsgi') -def subcommand_set_default(arguments): +@privileged +def set_default(permissions: list[str]): """Set default permissions.""" - conf = {'DEFAULT_PERMISSIONS': _format_permissions(arguments.permissions)} + conf = {'DEFAULT_PERMISSIONS': _format_permissions(permissions)} conf_file_write(conf) action_utils.service_try_restart('uwsgi') @@ -204,16 +168,3 @@ def _generate_password(): """Generate a random password.""" alphabet = string.ascii_letters + string.digits return ''.join(secrets.choice(alphabet) for _ in range(PASSWORD_LENGTH)) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/bepasty/views.py b/plinth/modules/bepasty/views.py index 74da52ac8..58347099c 100644 --- a/plinth/modules/bepasty/views.py +++ b/plinth/modules/bepasty/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the bepasty app. -""" +"""Views for the bepasty app.""" from django.contrib import messages from django.contrib.messages.views import SuccessMessageMixin @@ -11,10 +9,9 @@ from django.utils.translation import gettext_lazy as _ from django.views.decorators.http import require_POST from django.views.generic import FormView -from plinth.errors import ActionError -from plinth.modules import bepasty from plinth.views import AppView +from . import privileged from .forms import AddPasswordForm, SetDefaultPermissionsForm # i18n for permission comments @@ -27,6 +24,7 @@ PERMISSION_COMMENTS_STRINGS = { class BepastyView(AppView): """Serve configuration page.""" + app_id = 'bepasty' form_class = SetDefaultPermissionsForm template_name = 'bepasty.html' @@ -39,7 +37,7 @@ class BepastyView(AppView): def _get_configuration(self): """Return the current configuration.""" if not self.conf: - self.conf = bepasty.get_configuration() + self.conf = privileged.get_configuration() return self.conf @@ -85,10 +83,10 @@ class BepastyView(AppView): if old_data['default_permissions'] != form_data['default_permissions']: try: - bepasty.set_default_permissions( - form_data['default_permissions']) + privileged.set_default( + form_data['default_permissions'].split(' ')) messages.success(self.request, _('Configuration updated.')) - except ActionError: + except Exception: messages.error(self.request, _('An error occurred during configuration.')) @@ -112,17 +110,14 @@ class AddPasswordView(SuccessMessageMixin, FormView): def form_valid(self, form): """Add the password on valid form submission.""" - _add_password(form.cleaned_data) + form_data = form.cleaned_data + privileged.add_password(form_data['permissions'], form_data['comment']) return super().form_valid(form) -def _add_password(form_data): - bepasty.add_password(form_data['permissions'], form_data['comment']) - - @require_POST def remove(request, password): """View to remove a password.""" - bepasty.remove_password(password) + privileged.remove_password(password) messages.success(request, _('Password deleted.')) return redirect(reverse_lazy('bepasty:index')) diff --git a/plinth/modules/bind/__init__.py b/plinth/modules/bind/__init__.py index ff61d51f4..fe2f114a5 100644 --- a/plinth/modules/bind/__init__.py +++ b/plinth/modules/bind/__init__.py @@ -1,16 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure BIND server. -""" +"""FreedomBox app to configure BIND server.""" -import re -from collections import defaultdict -from pathlib import Path - -import augeas from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu from plinth.daemon import Daemon @@ -19,7 +11,7 @@ from plinth.modules.firewall.components import Firewall from plinth.package import Packages, install from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('BIND enables you to publish your Domain Name System (DNS) information ' @@ -32,39 +24,13 @@ _description = [ box_name=_(cfg.box_name)), ] -CONFIG_FILE = '/etc/bind/named.conf.options' -ZONES_DIR = '/var/bind/pri' - -DEFAULT_CONFIG = ''' -acl goodclients { - localnets; -}; -options { -directory "/var/cache/bind"; - -recursion yes; -allow-query { goodclients; }; - -forwarders { - -}; -forward first; - -dnssec-enable yes; -dnssec-validation auto; - -auth-nxdomain no; # conform to RFC1035 -listen-on-v6 { any; }; -}; -''' - class BindApp(app_module.App): """FreedomBox app for Bind.""" app_id = 'bind' - _version = 2 + _version = 3 def __init__(self): """Create components for the app.""" @@ -100,154 +66,10 @@ class BindApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('bind', - ['setup', '--old-version', - str(old_version)]) + privileged.setup(old_version) self.enable() def force_upgrade(self, _packages): """Force upgrade the managed packages to resolve conffile prompt.""" install(['bind9'], force_configuration='old') return True - - -def get_config(): - """Get current configuration""" - data = [line.strip() for line in open(CONFIG_FILE, 'r', encoding='utf-8')] - - forwarders = '' - dnssec_enabled = False - flag = False - for line in data: - if re.match(r'^\s*forwarders\s+{', line): - flag = True - elif re.match(r'^\s*dnssec-enable\s+yes;', line): - dnssec_enabled = True - elif flag and '//' not in line: - forwarders = re.sub('[;]', '', line) - flag = False - - conf = { - 'forwarders': forwarders, - 'enable_dnssec': dnssec_enabled, - } - return conf - - -def set_forwarders(forwarders): - """Set DNS forwarders.""" - flag = 0 - data = [line.strip() for line in open(CONFIG_FILE, 'r', encoding='utf-8')] - conf_file = open(CONFIG_FILE, 'w', encoding='utf-8') - for line in data: - if re.match(r'^\s*forwarders\s+{', line): - conf_file.write(line + '\n') - for dns in forwarders.split(): - conf_file.write(dns + '; ') - conf_file.write('\n') - flag = 1 - elif '};' in line and flag == 1: - conf_file.write(line + '\n') - flag = 0 - elif flag == 0: - conf_file.write(line + '\n') - conf_file.close() - - -def set_dnssec(choice): - """Enable or disable DNSSEC.""" - data = [line.strip() for line in open(CONFIG_FILE, 'r', encoding='utf-8')] - - if choice == 'enable': - conf_file = open(CONFIG_FILE, 'w', encoding='utf-8') - for line in data: - if re.match(r'//\s*dnssec-enable\s+yes;', line): - line = line.lstrip('/') - conf_file.write(line + '\n') - conf_file.close() - - if choice == 'disable': - conf_file = open(CONFIG_FILE, 'w', encoding='utf-8') - for line in data: - if re.match(r'^\s*dnssec-enable\s+yes;', line): - line = '//' + line - conf_file.write(line + '\n') - conf_file.close() - - -def get_served_domains(): - """ - - Augeas path for zone files: - =========================== - augtool> print /files/var/bind/pri/local.zone - /files/var/bind/pri/local.zone - /files/var/bind/pri/local.zone/$TTL = "604800" - /files/var/bind/pri/local.zone/@[1] - /files/var/bind/pri/local.zone/@[1]/1 - /files/var/bind/pri/local.zone/@[1]/1/class = "IN" - /files/var/bind/pri/local.zone/@[1]/1/type = "SOA" - /files/var/bind/pri/local.zone/@[1]/1/mname = "localhost." - /files/var/bind/pri/local.zone/@[1]/1/rname = "root.localhost." - /files/var/bind/pri/local.zone/@[1]/1/serial = "2" - /files/var/bind/pri/local.zone/@[1]/1/refresh = "604800" - /files/var/bind/pri/local.zone/@[1]/1/retry = "86400" - /files/var/bind/pri/local.zone/@[1]/1/expiry = "2419200" - /files/var/bind/pri/local.zone/@[1]/1/minimum = "604800" - /files/var/bind/pri/local.zone/@[2] - /files/var/bind/pri/local.zone/@[2]/1 - /files/var/bind/pri/local.zone/@[2]/1/class = "IN" - /files/var/bind/pri/local.zone/@[2]/1/type = "NS" - /files/var/bind/pri/local.zone/@[2]/1/rdata = "localhost." - /files/var/bind/pri/local.zone/@[3] - /files/var/bind/pri/local.zone/@[3]/1 - /files/var/bind/pri/local.zone/@[3]/1/class = "IN" - /files/var/bind/pri/local.zone/@[3]/1/type = "A" - /files/var/bind/pri/local.zone/@[3]/1/rdata = "127.0.0.1" - /files/var/bind/pri/local.zone/@[4] - /files/var/bind/pri/local.zone/@[4]/1 - /files/var/bind/pri/local.zone/@[4]/1/class = "IN" - /files/var/bind/pri/local.zone/@[4]/1/type = "AAAA" - /files/var/bind/pri/local.zone/@[4]/1/rdata = "::1" - - Need to find the related functionality to parse the A records - - Retrieve from /etc/bind/db* zone files all the configured A records. - Assuming zones files in ZONES_DIR are all used. - :return: dictionary in the form 'domain_name': ['ip_address', 'ipv6_addr'] - """ - RECORD_TYPES = ('A', 'AAAA') - aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + - augeas.Augeas.NO_MODL_AUTOLOAD) - aug.set('/augeas/load/Dns_Zone/lens', 'Dns_Zone.lns') - - zone_file_path = Path(ZONES_DIR) - zone_files = [zf for zf in zone_file_path.iterdir() if zf.is_file()] - - # augeas load only required files - for zone_file in zone_files: - aug.set('/augeas/load/Dns_Zone/incl[last() + 1]', str(zone_file)) - - aug.load() - - served_domains = defaultdict(list) - for zone_file in zone_files: - base_path = '/files/%s/@[{record_order}]/1/{field}' % zone_file - count = 1 - mname = aug.get(base_path.format(record_order=count, field='mname')) - while True: - record_type = aug.get( - base_path.format(record_order=count, field='type')) - - # no record type ends the search - if record_type is None: - break - - if record_type in RECORD_TYPES: - served_domains[mname].append( - aug.get(base_path.format(record_order=count, - field='rdata'))) - - count += 1 - - return served_domains diff --git a/plinth/modules/bind/forms.py b/plinth/modules/bind/forms.py index 36cca46cc..95e87407e 100644 --- a/plinth/modules/bind/forms.py +++ b/plinth/modules/bind/forms.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Forms for BIND module. -""" +"""Forms for BIND module.""" from django import forms from django.core.validators import validate_ipv46_address @@ -15,12 +13,9 @@ def validate_ips(ips): class BindForm(forms.Form): - """BIND configuration form""" + """BIND configuration form.""" + forwarders = forms.CharField( label=_('Forwarders'), required=False, validators=[validate_ips], help_text=_('A list DNS servers, separated by space, to which ' 'requests will be forwarded')) - - enable_dnssec = forms.BooleanField( - label=_('Enable DNSSEC'), required=False, - help_text=_('Enable Domain Name System Security Extensions')) diff --git a/plinth/modules/bind/privileged.py b/plinth/modules/bind/privileged.py new file mode 100644 index 000000000..0e1713229 --- /dev/null +++ b/plinth/modules/bind/privileged.py @@ -0,0 +1,179 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configuration helper for BIND server.""" + +import re +from collections import defaultdict +from pathlib import Path + +import augeas + +from plinth import action_utils +from plinth.actions import privileged + +CONFIG_FILE = '/etc/bind/named.conf.options' +ZONES_DIR = '/var/bind/pri' + +DEFAULT_CONFIG = ''' +acl goodclients { + localnets; +}; +options { +directory "/var/cache/bind"; + +recursion yes; +allow-query { goodclients; }; + +forwarders { + +}; +forward first; + +auth-nxdomain no; # conform to RFC1035 +listen-on-v6 { any; }; +}; +''' + + +@privileged +def setup(old_version: int): + """Setup BIND configuration.""" + if old_version == 0: + with open(CONFIG_FILE, 'w', encoding='utf-8') as conf_file: + conf_file.write(DEFAULT_CONFIG) + elif old_version < 3: + _remove_dnssec() + + Path(ZONES_DIR).mkdir(exist_ok=True, parents=True) + + action_utils.service_restart('named') + + +@privileged +def configure(forwarders: str): + """Configure BIND.""" + _set_forwarders(forwarders) + action_utils.service_restart('named') + + +def get_config(): + """Get current configuration.""" + data = [line.strip() for line in open(CONFIG_FILE, 'r', encoding='utf-8')] + + forwarders = '' + flag = False + for line in data: + if re.match(r'^\s*forwarders\s+{', line): + flag = True + elif flag and '//' not in line: + forwarders = re.sub('[;]', '', line) + flag = False + + return {'forwarders': forwarders} + + +def _set_forwarders(forwarders): + """Set DNS forwarders.""" + flag = 0 + data = [line.strip() for line in open(CONFIG_FILE, 'r', encoding='utf-8')] + conf_file = open(CONFIG_FILE, 'w', encoding='utf-8') + for line in data: + if re.match(r'^\s*forwarders\s+{', line): + conf_file.write(line + '\n') + for dns in forwarders.split(): + conf_file.write(dns + '; ') + conf_file.write('\n') + flag = 1 + elif '};' in line and flag == 1: + conf_file.write(line + '\n') + flag = 0 + elif flag == 0: + conf_file.write(line + '\n') + conf_file.close() + + +def _remove_dnssec(): + """Remove DNSSEC options.""" + data = [line.strip() for line in open(CONFIG_FILE, 'r', encoding='utf-8')] + + with open(CONFIG_FILE, 'w', encoding='utf-8') as file_handle: + for line in data: + if not re.match(r'^\s*dnssec-enable\s+yes;', line): + file_handle.write(line + '\n') + + +def get_served_domains(): + """Return list of domains service handles. + + Augeas path for zone files: + =========================== + augtool> print /files/var/bind/pri/local.zone + /files/var/bind/pri/local.zone + /files/var/bind/pri/local.zone/$TTL = "604800" + /files/var/bind/pri/local.zone/@[1] + /files/var/bind/pri/local.zone/@[1]/1 + /files/var/bind/pri/local.zone/@[1]/1/class = "IN" + /files/var/bind/pri/local.zone/@[1]/1/type = "SOA" + /files/var/bind/pri/local.zone/@[1]/1/mname = "localhost." + /files/var/bind/pri/local.zone/@[1]/1/rname = "root.localhost." + /files/var/bind/pri/local.zone/@[1]/1/serial = "2" + /files/var/bind/pri/local.zone/@[1]/1/refresh = "604800" + /files/var/bind/pri/local.zone/@[1]/1/retry = "86400" + /files/var/bind/pri/local.zone/@[1]/1/expiry = "2419200" + /files/var/bind/pri/local.zone/@[1]/1/minimum = "604800" + /files/var/bind/pri/local.zone/@[2] + /files/var/bind/pri/local.zone/@[2]/1 + /files/var/bind/pri/local.zone/@[2]/1/class = "IN" + /files/var/bind/pri/local.zone/@[2]/1/type = "NS" + /files/var/bind/pri/local.zone/@[2]/1/rdata = "localhost." + /files/var/bind/pri/local.zone/@[3] + /files/var/bind/pri/local.zone/@[3]/1 + /files/var/bind/pri/local.zone/@[3]/1/class = "IN" + /files/var/bind/pri/local.zone/@[3]/1/type = "A" + /files/var/bind/pri/local.zone/@[3]/1/rdata = "127.0.0.1" + /files/var/bind/pri/local.zone/@[4] + /files/var/bind/pri/local.zone/@[4]/1 + /files/var/bind/pri/local.zone/@[4]/1/class = "IN" + /files/var/bind/pri/local.zone/@[4]/1/type = "AAAA" + /files/var/bind/pri/local.zone/@[4]/1/rdata = "::1" + + Need to find the related functionality to parse the A records + + Retrieve from /etc/bind/db* zone files all the configured A records. + Assuming zones files in ZONES_DIR are all used. + :return: dictionary in the form 'domain_name': ['ip_address', 'ipv6_addr'] + """ + RECORD_TYPES = ('A', 'AAAA') + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) + aug.set('/augeas/load/Dns_Zone/lens', 'Dns_Zone.lns') + + zone_file_path = Path(ZONES_DIR) + zone_files = [zf for zf in zone_file_path.iterdir() if zf.is_file()] + + # augeas load only required files + for zone_file in zone_files: + aug.set('/augeas/load/Dns_Zone/incl[last() + 1]', str(zone_file)) + + aug.load() + + served_domains = defaultdict(list) + for zone_file in zone_files: + base_path = '/files/%s/@[{record_order}]/1/{field}' % zone_file + count = 1 + mname = aug.get(base_path.format(record_order=count, field='mname')) + while True: + record_type = aug.get( + base_path.format(record_order=count, field='type')) + + # no record type ends the search + if record_type is None: + break + + if record_type in RECORD_TYPES: + served_domains[mname].append( + aug.get(base_path.format(record_order=count, + field='rdata'))) + + count += 1 + + return served_domains diff --git a/plinth/modules/bind/tests/test_bind.py b/plinth/modules/bind/tests/test_bind.py index 94d8743bd..6131893a9 100644 --- a/plinth/modules/bind/tests/test_bind.py +++ b/plinth/modules/bind/tests/test_bind.py @@ -13,11 +13,11 @@ from plinth.modules import bind def fixture_configuration_file(tmp_path): """Setup the a bind configuration file temporary directory.""" conf_file = tmp_path / 'named.conf.options' - conf_file.write_text(bind.DEFAULT_CONFIG) - old_config_file = bind.CONFIG_FILE - bind.CONFIG_FILE = str(conf_file) + conf_file.write_text(bind.privileged.DEFAULT_CONFIG) + old_config_file = bind.privileged.CONFIG_FILE + bind.privileged.CONFIG_FILE = str(conf_file) yield - bind.CONFIG_FILE = old_config_file + bind.privileged.CONFIG_FILE = old_config_file @pytest.fixture @@ -40,62 +40,49 @@ $TTL 604800 @ IN AAAA {aaaa_record} """ # noqa - old_zones_dir = bind.ZONES_DIR - bind.ZONES_DIR = tmp_path - zones_dir_path = Path(bind.ZONES_DIR) + old_zones_dir = bind.privileged.ZONES_DIR + bind.privileged.ZONES_DIR = tmp_path + zones_dir_path = Path(bind.privileged.ZONES_DIR) zones_dir_path.mkdir(exist_ok=True, parents=True) local_path = zones_dir_path / "local.zone" local_path.write_text( test_zone_file.format(name='localhost.', a_record="127.0.0.1", - aaaa_record="::1") - ) + aaaa_record="::1")) custom_zone_path = zones_dir_path / "custom.zone" custom_zone_path.write_text( test_zone_file.format(name='custom.domain.', a_record="10.10.10.1", - aaaa_record="fe80::c6e9:84ff:fe16:95da") - ) + aaaa_record="fe80::c6e9:84ff:fe16:95da")) yield local_path.unlink() custom_zone_path.unlink() - bind.ZONES_DIR = old_zones_dir + bind.privileged.ZONES_DIR = old_zones_dir @pytest.mark.usefixtures('configuration_file') def test_set_forwarders(): """Test that setting forwarders works.""" - bind.set_forwarders('8.8.8.8 8.8.4.4') - conf = bind.get_config() + bind.privileged._set_forwarders('8.8.8.8 8.8.4.4') + conf = bind.privileged.get_config() assert conf['forwarders'] == '8.8.8.8 8.8.4.4' - bind.set_forwarders('') - conf = bind.get_config() + bind.privileged._set_forwarders('') + conf = bind.privileged.get_config() assert conf['forwarders'] == '' -@pytest.mark.usefixtures('configuration_file') -def test_enable_dnssec(): - """Test that enabling DNSSEC works.""" - bind.set_dnssec('enable') - conf = bind.get_config() - assert conf['enable_dnssec'] - - bind.set_dnssec('disable') - conf = bind.get_config() - assert not conf['enable_dnssec'] - - @pytest.mark.usefixtures('bind_zones_folder') def test_get_correct_served_domains(): """ Test that get_served_domains collects the right a/aaaa records from zone files """ - served_domains = bind.get_served_domains() + served_domains = bind.privileged.get_served_domains() assert served_domains['localhost.'] == ["127.0.0.1", "::1"] assert served_domains['custom.domain.'] == [ - "10.10.10.1", "fe80::c6e9:84ff:fe16:95da"] + "10.10.10.1", "fe80::c6e9:84ff:fe16:95da" + ] diff --git a/plinth/modules/bind/tests/test_functional.py b/plinth/modules/bind/tests/test_functional.py index fc43e6ab6..99f2c1e0c 100644 --- a/plinth/modules/bind/tests/test_functional.py +++ b/plinth/modules/bind/tests/test_functional.py @@ -23,45 +23,14 @@ class TestBindApp(functional.BaseAppTests): functional.set_forwarders(session_browser, '1.1.1.1 1.0.0.1') assert functional.get_forwarders(session_browser) == '1.1.1.1 1.0.0.1' - def test_enable_disable_dnssec(self, session_browser): - """Test enabling/disabling DNSSEC.""" - functional.app_enable(session_browser, 'bind') - _enable_dnssec(session_browser, False) - - _enable_dnssec(session_browser, True) - assert _get_dnssec(session_browser) - - _enable_dnssec(session_browser, False) - assert not _get_dnssec(session_browser) - @pytest.mark.backups def test_backup_restore(self, session_browser): """Test backup and restore.""" functional.app_enable(session_browser, 'bind') functional.set_forwarders(session_browser, '1.1.1.1') - _enable_dnssec(session_browser, False) functional.backup_create(session_browser, 'bind', 'test_bind') functional.set_forwarders(session_browser, '1.0.0.1') - _enable_dnssec(session_browser, True) functional.backup_restore(session_browser, 'bind', 'test_bind') assert functional.get_forwarders(session_browser) == '1.1.1.1' - assert not _get_dnssec(session_browser) - - -def _enable_dnssec(browser, enable): - """Enable/disable DNSSEC in bind configuration.""" - functional.nav_to_module(browser, 'bind') - if enable: - browser.check('enable_dnssec') - else: - browser.uncheck('enable_dnssec') - - functional.submit(browser, form_class='form-configuration') - - -def _get_dnssec(browser): - """Return whether DNSSEC is enabled/disabled in bind configuration.""" - functional.nav_to_module(browser, 'bind') - return browser.find_by_name('enable_dnssec').first.checked diff --git a/plinth/modules/bind/views.py b/plinth/modules/bind/views.py index 4300eeddb..d5de97387 100644 --- a/plinth/modules/bind/views.py +++ b/plinth/modules/bind/views.py @@ -1,33 +1,28 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for BIND module. -""" +"""Views for BIND module.""" from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from plinth import actions -from plinth.modules import bind, names +from plinth.modules import names from plinth.views import AppView -from . import get_config +from . import privileged from .forms import BindForm class BindAppView(AppView): # pylint: disable=too-many-ancestors """A specialized view for configuring Bind.""" + app_id = 'bind' form_class = BindForm template_name = 'bind.html' def get_context_data(self, *args, **kwargs): - """ - Get/append information for domains bind is configured to respond for - and additional names from the names module - """ + """Get/append information for domains and additional names.""" context = super().get_context_data(**kwargs) - served_domains = bind.get_served_domains() + served_domains = privileged.get_served_domains() context['domains_table'] = [] for key, val in served_domains.items(): if key == 'localhost.': @@ -53,21 +48,16 @@ class BindAppView(AppView): # pylint: disable=too-many-ancestors def get_initial(self): """Return the values to fill in the form.""" initial = super().get_initial() - initial.update(get_config()) + initial.update(privileged.get_config()) return initial def form_valid(self, form): """Change the configurations of Bind service.""" data = form.cleaned_data - old_config = get_config() + old_config = privileged.get_config() - if old_config['forwarders'] != data['forwarders'] \ - or old_config['enable_dnssec'] != data['enable_dnssec']: - dnssec_setting = 'enable' if data['enable_dnssec'] else 'disable' - actions.superuser_run('bind', [ - 'configure', '--forwarders', data['forwarders'], '--dnssec', - dnssec_setting - ]) + if old_config['forwarders'] != data['forwarders']: + privileged.configure(data['forwarders']) messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/calibre/__init__.py b/plinth/modules/calibre/__init__.py index 93aeb164d..9dc446f29 100644 --- a/plinth/modules/calibre/__init__.py +++ b/plinth/modules/calibre/__init__.py @@ -1,14 +1,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for calibre e-book library. -""" +"""FreedomBox app for calibre e-book library.""" -import json import re from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -109,21 +105,3 @@ def validate_library_name(library_name): """Raise exception if library name does not fit the accepted pattern.""" if not re.fullmatch(r'[A-Za-z0-9_.-]+', library_name): raise Exception('Invalid library name') - - -def list_libraries(): - """Return a list of libraries.""" - output = actions.superuser_run('calibre', ['list-libraries']) - return json.loads(output)['libraries'] - - -def create_library(name): - """Create an empty library.""" - actions.superuser_run('calibre', ['create-library', name]) - actions.superuser_run('service', ['try-restart', CalibreApp.DAEMON]) - - -def delete_library(name): - """Delete a library and its contents.""" - actions.superuser_run('calibre', ['delete-library', name]) - actions.superuser_run('service', ['try-restart', CalibreApp.DAEMON]) diff --git a/plinth/modules/calibre/forms.py b/plinth/modules/calibre/forms.py index 378c43420..085413277 100644 --- a/plinth/modules/calibre/forms.py +++ b/plinth/modules/calibre/forms.py @@ -1,14 +1,12 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Django form for configuring calibre. -""" +"""Django form for configuring calibre.""" from django import forms from django.core import validators from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ -from plinth.modules import calibre +from . import privileged class CreateLibraryForm(forms.Form): @@ -25,7 +23,7 @@ class CreateLibraryForm(forms.Form): """Check if the library name is valid.""" name = self.cleaned_data['name'] - if name in calibre.list_libraries(): + if name in privileged.list_libraries(): raise ValidationError( _('A library with this name already exists.')) diff --git a/plinth/modules/calibre/privileged.py b/plinth/modules/calibre/privileged.py new file mode 100644 index 000000000..88db062fc --- /dev/null +++ b/plinth/modules/calibre/privileged.py @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configuration helper for calibre.""" + +import pathlib +import shutil +import subprocess + +from plinth import action_utils +from plinth.actions import privileged +from plinth.modules import calibre + +LIBRARIES_PATH = pathlib.Path('/var/lib/calibre-server-freedombox/libraries') + + +@privileged +def list_libraries() -> list[str]: + """Return the list of libraries setup.""" + libraries = [] + for library in LIBRARIES_PATH.glob('*/metadata.db'): + libraries.append(str(library.parent.name)) + + return libraries + + +@privileged +def create_library(name: str): + """Create an empty library.""" + calibre.validate_library_name(name) + library = LIBRARIES_PATH / name + library.mkdir(mode=0o755) # Raise exception if already exists + subprocess.call( + ['calibredb', '--with-library', library, 'list_categories'], + stdout=subprocess.DEVNULL) + + # Force systemd StateDirectory= logic to assign proper ownership to the + # DynamicUser= + shutil.chown(LIBRARIES_PATH.parent, 'root', 'root') + action_utils.service_try_restart(calibre.CalibreApp.DAEMON) + + +@privileged +def delete_library(name: str): + """Delete a library and its contents.""" + calibre.validate_library_name(name) + library = LIBRARIES_PATH / name + shutil.rmtree(library) + action_utils.service_try_restart(calibre.CalibreApp.DAEMON) diff --git a/plinth/modules/calibre/tests/test_actions.py b/plinth/modules/calibre/tests/test_actions.py deleted file mode 100644 index 5708c011e..000000000 --- a/plinth/modules/calibre/tests/test_actions.py +++ /dev/null @@ -1,67 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Test module for calibre actions. -""" - -import json -import pathlib -from unittest.mock import call, patch - -import pytest - -actions_name = 'calibre' - - -@pytest.fixture(autouse=True) -def fixture_libraries_path(actions_module, tmpdir): - """Set the libraries path in the actions module.""" - actions_module.LIBRARIES_PATH = pathlib.Path(str(tmpdir)) - - -@pytest.fixture(autouse=True) -def fixture_patch(): - """Patch some underlying methods.""" - - def side_effect(*args, **_kwargs): - if args[0][0] != 'calibredb': - return - - path = pathlib.Path(args[0][2]) / 'metadata.db' - path.touch() - - with patch('subprocess.call') as subprocess_call, \ - patch('shutil.chown'): - subprocess_call.side_effect = side_effect - yield - - -def test_list_libraries(call_action): - """Test listing libraries.""" - assert json.loads(call_action(['list-libraries'])) == {'libraries': []} - call_action(['create-library', 'TestLibrary']) - expected_output = {'libraries': ['TestLibrary']} - assert json.loads(call_action(['list-libraries'])) == expected_output - - -@patch('shutil.chown') -def test_create_library(chown, call_action, actions_module): - """Test creating a library.""" - call_action(['create-library', 'TestLibrary']) - library = actions_module.LIBRARIES_PATH / 'TestLibrary' - assert (library / 'metadata.db').exists() - assert library.stat().st_mode == 0o40755 - expected_output = {'libraries': ['TestLibrary']} - assert json.loads(call_action(['list-libraries'])) == expected_output - - chown.assert_has_calls([call(library.parent.parent, 'root', 'root')]) - - -def test_delete_library(call_action): - """Test deleting a library.""" - call_action(['create-library', 'TestLibrary']) - - call_action(['delete-library', 'TestLibrary']) - assert json.loads(call_action(['list-libraries'])) == {'libraries': []} - - with pytest.raises(FileNotFoundError): - call_action(['delete-library', 'TestLibrary']) diff --git a/plinth/modules/calibre/tests/test_privileged.py b/plinth/modules/calibre/tests/test_privileged.py new file mode 100644 index 000000000..6b41173f8 --- /dev/null +++ b/plinth/modules/calibre/tests/test_privileged.py @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Test module for calibre actions.""" + +import pathlib +from unittest.mock import call, patch + +import pytest + +from plinth.modules.calibre import privileged + +pytestmark = pytest.mark.usefixtures('mock_privileged') +privileged_modules_to_mock = ['plinth.modules.calibre.privileged'] + + +@pytest.fixture(autouse=True) +def fixture_libraries_path(tmpdir): + """Set the libraries path in the actions module.""" + privileged.LIBRARIES_PATH = pathlib.Path(str(tmpdir)) + + +@pytest.fixture(autouse=True) +def fixture_patch(): + """Patch some underlying methods.""" + + def side_effect(*args, **_kwargs): + if args[0][0] != 'calibredb': + return + + path = pathlib.Path(args[0][2]) / 'metadata.db' + path.touch() + + with patch('subprocess.call') as subprocess_call, \ + patch('subprocess.run'), patch('shutil.chown'): + subprocess_call.side_effect = side_effect + yield + + +def test_list_libraries(): + """Test listing libraries.""" + assert privileged.list_libraries() == [] + privileged.create_library('TestLibrary') + assert privileged.list_libraries() == ['TestLibrary'] + + +@patch('shutil.chown') +def test_create_library(chown): + """Test creating a library.""" + privileged.create_library('TestLibrary') + library = privileged.LIBRARIES_PATH / 'TestLibrary' + assert (library / 'metadata.db').exists() + assert library.stat().st_mode == 0o40755 + assert privileged.list_libraries() == ['TestLibrary'] + + chown.assert_has_calls([call(library.parent.parent, 'root', 'root')]) + + +def test_delete_library(): + """Test deleting a library.""" + privileged.create_library('TestLibrary') + privileged.delete_library('TestLibrary') + assert privileged.list_libraries() == [] + + with pytest.raises(FileNotFoundError): + privileged.delete_library('TestLibrary') diff --git a/plinth/modules/calibre/tests/test_views.py b/plinth/modules/calibre/tests/test_views.py index d1ee16747..c7076ac91 100644 --- a/plinth/modules/calibre/tests/test_views.py +++ b/plinth/modules/calibre/tests/test_views.py @@ -10,7 +10,7 @@ from django import urls from django.contrib.messages.storage.fallback import FallbackStorage from django.http.response import Http404 -from plinth import actions, module_loader +from plinth import module_loader from plinth.modules.calibre import views # For all tests, use plinth.urls instead of urls configured for testing @@ -30,7 +30,8 @@ def fixture_calibre_urls(): @pytest.fixture(autouse=True) def calibre_patch(): """Patch calibre methods.""" - with patch('plinth.modules.calibre.list_libraries') as list_libraries: + with patch('plinth.modules.calibre.privileged.list_libraries' + ) as list_libraries: list_libraries.return_value = ['TestExistingLibrary'] yield @@ -46,7 +47,7 @@ def make_request(request, view, **kwargs): return response, messages -@patch('plinth.modules.calibre.create_library') +@patch('plinth.modules.calibre.privileged.create_library') def test_create_library(create_library, rf): """Test that create library view works.""" form_data = {'calibre-name': 'TestLibrary'} @@ -60,11 +61,10 @@ def test_create_library(create_library, rf): create_library.assert_has_calls([call('TestLibrary')]) -@patch('plinth.modules.calibre.create_library') +@patch('plinth.modules.calibre.privileged.create_library') def test_create_library_failed(create_library, rf): """Test that create library fails as expected.""" - create_library.side_effect = actions.ActionError('calibre', 'TestOutput', - 'TestError') + create_library.side_effect = RuntimeError('TestError') form_data = {'calibre-name': 'TestLibrary'} request = rf.post(urls.reverse('calibre:create-library'), data=form_data) view = views.CreateLibraryView.as_view() @@ -109,7 +109,7 @@ def test_delete_library_confirmation_view(_app, rf): assert response.context_data['name'] == 'TestExistingLibrary' -@patch('plinth.modules.calibre.delete_library') +@patch('plinth.modules.calibre.privileged.delete_library') @patch('plinth.app.App.get') def test_delete_library(_app, delete_library, rf): """Test that deleting a library works.""" @@ -121,18 +121,16 @@ def test_delete_library(_app, delete_library, rf): delete_library.assert_has_calls([call('TestExistingLibrary')]) -@patch('plinth.modules.calibre.delete_library') +@patch('plinth.modules.calibre.privileged.delete_library') def test_delete_library_error(delete_library, rf): """Test that deleting a library shows error when operation fails.""" - delete_library.side_effect = actions.ActionError('calibre', 'TestInput', - 'TestError') + delete_library.side_effect = ValueError('TestError') response, messages = make_request(rf.post(''), views.delete_library, name='TestExistingLibrary') assert response.status_code == 302 assert response.url == urls.reverse('calibre:index') assert list(messages)[0].message == \ - 'Could not delete TestExistingLibrary: '\ - "('calibre', 'TestInput', 'TestError')" + 'Could not delete TestExistingLibrary: TestError' def test_delete_library_non_existing(rf): diff --git a/plinth/modules/calibre/views.py b/plinth/modules/calibre/views.py index d8a9e6e5b..3db0fbfb5 100644 --- a/plinth/modules/calibre/views.py +++ b/plinth/modules/calibre/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the calibre module. -""" +"""Views for the calibre module.""" from django.contrib import messages from django.contrib.messages.views import SuccessMessageMixin @@ -12,28 +10,28 @@ from django.urls import reverse_lazy from django.utils.translation import gettext as _ from django.views.generic.edit import FormView -from plinth import actions from plinth import app as app_module from plinth import views -from plinth.modules import calibre -from . import forms +from . import forms, privileged class CalibreAppView(views.AppView): """Serve configuration form.""" + app_id = 'calibre' template_name = 'calibre.html' def get_context_data(self, **kwargs): """Return additional context for rendering the template.""" context = super().get_context_data(**kwargs) - context['libraries'] = calibre.list_libraries() + context['libraries'] = privileged.list_libraries() return context class CreateLibraryView(SuccessMessageMixin, FormView): """View to create an empty library.""" + form_class = forms.CreateLibraryForm prefix = 'calibre' template_name = 'form.html' @@ -43,28 +41,27 @@ class CreateLibraryView(SuccessMessageMixin, FormView): def form_valid(self, form): """Create the library on valid form submission.""" try: - calibre.create_library(form.cleaned_data['name']) - except actions.ActionError as error: + privileged.create_library(form.cleaned_data['name']) + except Exception as error: self.success_message = '' - error_text = error.args[2].split('\n')[0] messages.error( self.request, "{0} {1}".format( _('An error occurred while creating the library.'), - error_text)) + str(error))) return super().form_valid(form) def delete_library(request, name): """View to delete a library.""" - if name not in calibre.list_libraries(): + if name not in privileged.list_libraries(): raise Http404 if request.method == 'POST': try: - calibre.delete_library(name) + privileged.delete_library(name) messages.success(request, _('{name} deleted.').format(name=name)) - except actions.ActionError as error: + except Exception as error: messages.error( request, _('Could not delete {name}: {error}').format( diff --git a/plinth/modules/config/__init__.py b/plinth/modules/config/__init__.py index 80d2adb9e..b3ee55574 100644 --- a/plinth/modules/config/__init__.py +++ b/plinth/modules/config/__init__.py @@ -1,15 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for basic system configuration. -""" +"""FreedomBox app for basic system configuration.""" -import os import socket import augeas from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import RelatedDaemon @@ -17,6 +13,7 @@ from plinth.modules.apache import (get_users_with_website, user_of_uws_url, uws_url_of_user) from plinth.modules.names.components import DomainType from plinth.package import Packages +from plinth.privileged import service as service_privileged from plinth.signals import domain_added from . import privileged @@ -26,12 +23,6 @@ _description = [ 'like hostname, domain name, webserver home page etc.') ] -APACHE_CONF_ENABLED_DIR = '/etc/apache2/conf-enabled' -APACHE_HOMEPAGE_CONF_FILE_NAME = 'freedombox-apache-homepage.conf' -APACHE_HOMEPAGE_CONFIG = os.path.join(APACHE_CONF_ENABLED_DIR, - APACHE_HOMEPAGE_CONF_FILE_NAME) -FREEDOMBOX_APACHE_CONFIG = os.path.join(APACHE_CONF_ENABLED_DIR, - 'freedombox.conf') ADVANCED_MODE_KEY = 'advanced_mode' @@ -85,37 +76,35 @@ class ConfigApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - _migrate_home_page_config() if old_version <= 3: privileged.set_logging_mode('volatile') # systemd-journald is socket activated, it may not be running and it # does not support reload. - actions.superuser_run('service', ['try-restart', 'systemd-journald']) + service_privileged.try_restart('systemd-journald') # rsyslog when enabled, is activated by syslog.socket (shipped by # systemd). See: # https://www.freedesktop.org/wiki/Software/systemd/syslog/ . - actions.superuser_run('service', ['disable', 'rsyslog']) + service_privileged.disable('rsyslog') # Ensure that rsyslog is not started by something else as it is # installed by default on Debian systems. - actions.superuser_run('service', ['mask', 'rsyslog']) + service_privileged.mask('rsyslog') def get_domainname(): - """Return the domainname""" + """Return the domainname.""" fqdn = socket.getfqdn() return '.'.join(fqdn.split('.')[1:]) def get_hostname(): - """Return the hostname""" + """Return the hostname.""" return socket.gethostname() def home_page_url2scid(url): - """Returns the shortcut ID of the given home page url.""" - + """Return the shortcut ID of the given home page url.""" if url in ('/plinth/', '/plinth', 'plinth'): return 'plinth' @@ -134,7 +123,7 @@ def home_page_url2scid(url): def _home_page_scid2url(shortcut_id): - """Returns the url for the given home page shortcut ID.""" + """Return the url for the given home page shortcut ID.""" if shortcut_id is None: url = None elif shortcut_id == 'plinth': @@ -158,8 +147,9 @@ def _home_page_scid2url(shortcut_id): return url -def _get_home_page_url(conf_file): +def _get_home_page_url(): """Get the default application for the domain.""" + conf_file = privileged.APACHE_HOMEPAGE_CONFIG aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Httpd/lens', 'Httpd.lns') @@ -178,23 +168,18 @@ def _get_home_page_url(conf_file): def get_home_page(): """Return the shortcut ID that is set as current home page.""" - CONF_FILE = APACHE_HOMEPAGE_CONFIG if os.path.exists( - APACHE_HOMEPAGE_CONFIG) else FREEDOMBOX_APACHE_CONFIG - - url = _get_home_page_url(CONF_FILE) + url = _get_home_page_url() return home_page_url2scid(url) def change_home_page(shortcut_id): - """Change the FreedomBox's default redirect to URL of the shortcut - specified. - """ + """Change the FreedomBox's default redirect to URL of a shortcut.""" url = _home_page_scid2url(shortcut_id) if url is None: url = '/plinth/' # fall back to default url if scid is unknown. # URL may be a reverse_lazy() proxy - actions.superuser_run('config', ['set-home-page', str(url)]) + privileged.set_home_page(str(url)) def get_advanced_mode(): @@ -207,17 +192,3 @@ def set_advanced_mode(advanced_mode): """Turn on/off advanced mode.""" from plinth import kvstore kvstore.set(ADVANCED_MODE_KEY, advanced_mode) - - -def _migrate_home_page_config(): - """Move the home page configuration to an external file.""" - - # Hold the current home page in a variable - home_page = get_home_page() - - # Reset the home page to plinth in freedombox.conf - actions.superuser_run('config', ['reset-home-page']) - - # Write the home page setting into the new conf file - # This step is run at the end because it reloads the Apache server - change_home_page(home_page) diff --git a/plinth/modules/config/privileged.py b/plinth/modules/config/privileged.py index 264f668ae..24d38de49 100644 --- a/plinth/modules/config/privileged.py +++ b/plinth/modules/config/privileged.py @@ -1,16 +1,59 @@ # SPDX-License-Identifier: AGPL-3.0-or-later """Configure miscellaneous system settings.""" +import os import pathlib +import subprocess +from typing import Optional import augeas from plinth import action_utils from plinth.actions import privileged +APACHE_CONF_ENABLED_DIR = '/etc/apache2/conf-enabled' +APACHE_HOMEPAGE_CONF_FILE_NAME = 'freedombox-apache-homepage.conf' +APACHE_HOMEPAGE_CONFIG = os.path.join(APACHE_CONF_ENABLED_DIR, + APACHE_HOMEPAGE_CONF_FILE_NAME) + JOURNALD_FILE = pathlib.Path('/etc/systemd/journald.conf.d/50-freedombox.conf') +@privileged +def set_hostname(hostname: str): + """Set system hostname using hostnamectl.""" + subprocess.run( + ['hostnamectl', 'set-hostname', '--transient', '--static', hostname], + check=True) + action_utils.service_restart('avahi-daemon') + + +@privileged +def set_domainname(domainname: Optional[str] = None): + """Set system domainname in /etc/hosts.""" + hostname = subprocess.check_output(['hostname']).decode().strip() + hosts_path = pathlib.Path('/etc/hosts') + if domainname: + insert_line = f'127.0.1.1 {hostname}.{domainname} {hostname}\n' + else: + insert_line = f'127.0.1.1 {hostname}\n' + + lines = hosts_path.read_text(encoding='utf-8').splitlines(keepends=True) + new_lines = [] + found = False + for line in lines: + if '127.0.1.1' in line: + new_lines.append(insert_line) + found = True + else: + new_lines.append(line) + + if not found: + new_lines.append(insert_line) + + hosts_path.write_text(''.join(new_lines), encoding='utf-8') + + def load_augeas(): """Initialize Augeas.""" aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + @@ -34,7 +77,7 @@ def get_logging_mode() -> str: @privileged -def set_logging_mode(mode: str) -> None: +def set_logging_mode(mode: str): """Set the current logging mode.""" if mode not in ('volatile', 'persistent', 'none'): raise ValueError('Invalid mode') @@ -56,3 +99,17 @@ def set_logging_mode(mode: str) -> None: # systemd-journald is socket activated, it may not be running and it does # not support reload. action_utils.service_try_restart('systemd-journald') + + +@privileged +def set_home_page(homepage: str): + """Set the default app for this FreedomBox.""" + conf_file_path = os.path.join('/etc/apache2/conf-available', + APACHE_HOMEPAGE_CONF_FILE_NAME) + + redirect_rule = 'RedirectMatch "^/$" "{}"\n'.format(homepage) + + with open(conf_file_path, 'w', encoding='utf-8') as conf_file: + conf_file.write(redirect_rule) + + action_utils.webserver_enable('freedombox-apache-homepage') diff --git a/plinth/modules/config/views.py b/plinth/modules/config/views.py index 1e5599022..7a21b988a 100644 --- a/plinth/modules/config/views.py +++ b/plinth/modules/config/views.py @@ -1,14 +1,12 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox views for basic system configuration. -""" +"""FreedomBox views for basic system configuration.""" import logging from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions, views +from plinth import views from plinth.modules import config from plinth.signals import (domain_added, domain_removed, post_hostname_change, pre_hostname_change) @@ -21,11 +19,12 @@ LOGGER = logging.getLogger(__name__) class ConfigAppView(views.AppView): """Serve configuration page.""" + form_class = ConfigurationForm app_id = 'config' def get_initial(self): - """Return the current status""" + """Return the current status.""" return { 'hostname': config.get_hostname(), 'domainname': config.get_domainname(), @@ -35,7 +34,7 @@ class ConfigAppView(views.AppView): } def form_valid(self, form): - """Apply the form changes""" + """Apply the form changes.""" old_status = form.initial new_status = form.cleaned_data @@ -98,11 +97,11 @@ class ConfigAppView(views.AppView): if is_changed: messages.success(self.request, _('Configuration updated')) - return super(views.AppView, self).form_valid(form) + return super().form_valid(form) def set_hostname(hostname): - """Sets machine hostname to hostname""" + """Set machine hostname and send signals before and after.""" old_hostname = config.get_hostname() domainname = config.get_domainname() @@ -114,10 +113,10 @@ def set_hostname(hostname): new_hostname=hostname) LOGGER.info('Changing hostname to - %s', hostname) - actions.superuser_run('hostname-change', [hostname]) + privileged.set_hostname(hostname) LOGGER.info('Setting domain name after hostname change - %s', domainname) - actions.superuser_run('domainname-change', [domainname]) + privileged.set_domainname(domainname) post_hostname_change.send_robust(sender='config', old_hostname=old_hostname, @@ -125,7 +124,7 @@ def set_hostname(hostname): def set_domainname(domainname, old_domainname): - """Sets machine domain name to domainname""" + """Set machine domain name to domainname.""" old_domainname = config.get_domainname() # Domain name is not case sensitive, but Let's Encrypt certificate @@ -133,7 +132,7 @@ def set_domainname(domainname, old_domainname): domainname = domainname.lower() LOGGER.info('Changing domain name to - %s', domainname) - actions.superuser_run('domainname-change', [domainname]) + privileged.set_domainname(domainname) # Update domain registered with Name Services module. if old_domainname: diff --git a/plinth/modules/coturn/__init__.py b/plinth/modules/coturn/__init__.py index 71498f5e8..a3c424191 100644 --- a/plinth/modules/coturn/__init__.py +++ b/plinth/modules/coturn/__init__.py @@ -1,16 +1,12 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Coturn server. -""" +"""FreedomBox app to configure Coturn server.""" -import json import logging import pathlib from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import menu from plinth.daemon import Daemon @@ -23,7 +19,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('Coturn is a server to facilitate audio/video calls and conferences by ' @@ -109,7 +105,7 @@ class CoturnApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('coturn', ['setup']) + privileged.setup() if old_version == 0: self.enable() @@ -151,14 +147,13 @@ def get_domains(): def set_domain(domain): """Set the TLS domain by writing a file to data directory.""" if domain: - actions.superuser_run('coturn', ['set-domain', domain]) + privileged.set_domain(domain) notify_configuration_change() def get_config(): """Return the coturn server configuration.""" - output = actions.superuser_run('coturn', ['get-config']) - config = json.loads(output) + config = privileged.get_config() return TurnConfiguration(config['realm'], [], config['static_auth_secret']) diff --git a/actions/coturn b/plinth/modules/coturn/privileged.py old mode 100755 new mode 100644 similarity index 65% rename from actions/coturn rename to plinth/modules/coturn/privileged.py index 38a2e1719..14f75feb4 --- a/actions/coturn +++ b/plinth/modules/coturn/privileged.py @@ -1,11 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Coturn daemon. -""" +"""Configuration helper for Coturn daemon.""" -import argparse -import json import pathlib import random import shutil @@ -14,31 +9,18 @@ import string import augeas from plinth import action_utils +from plinth.actions import privileged CONFIG_FILE = pathlib.Path('/etc/coturn/freedombox.conf') -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Setup Coturn server') - subparsers.add_parser('get-config', - help='Return the current configuration') - subparser = subparsers.add_parser('set-domain', help='Set the TLS domain') - subparser.add_argument('domain_name', help='TLS domain name to set') - - subparsers.required = True - return parser.parse_args() - - def _key_path(key): """Return the augeas path for a key.""" return '/files' + str(CONFIG_FILE) + '/' + key -def subcommand_setup(_): +@privileged +def setup(): """Setup Coturn server.""" CONFIG_FILE.parent.mkdir(exist_ok=True) if not CONFIG_FILE.exists(): @@ -75,25 +57,26 @@ def subcommand_setup(_): action_utils.service_try_restart('coturn') -def subcommand_get_config(_): - """Return the current configuration in JSON format.""" +@privileged +def get_config() -> dict[str, str]: + """Return the current configuration.""" aug = augeas_load() config = { 'static_auth_secret': aug.get(_key_path('static-auth-secret')), 'realm': aug.get(_key_path('realm')), } - print(json.dumps(config)) + return config -def subcommand_set_domain(arguments): +@privileged +def set_domain(domain_name: str): """Set the TLS domain. This value is usually not stored. So, set realm value even though it is not needed to set realm for REST API based authentication. - """ aug = augeas_load() - aug.set(_key_path('realm'), arguments.domain_name) + aug.set(_key_path('realm'), domain_name) aug.save() @@ -106,16 +89,3 @@ def augeas_load(): aug.load() return aug - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/coturn/views.py b/plinth/modules/coturn/views.py index 25e6e46b7..383e7f150 100644 --- a/plinth/modules/coturn/views.py +++ b/plinth/modules/coturn/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for Coturn app. -""" +"""Views for Coturn app.""" from django.contrib import messages from django.utils.translation import gettext_lazy as _ @@ -15,6 +13,7 @@ from . import forms class CoturnAppView(views.AppView): """Serve configuration page.""" + app_id = 'coturn' template_name = 'coturn.html' form_class = forms.CoturnForm diff --git a/plinth/modules/datetime/privileged.py b/plinth/modules/datetime/privileged.py new file mode 100644 index 000000000..45790405e --- /dev/null +++ b/plinth/modules/datetime/privileged.py @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Set time zone with timedatectl.""" + +import subprocess + +from plinth.actions import privileged + + +@privileged +def set_timezone(timezone: str): + """Set time zone with timedatectl.""" + command = ['timedatectl', 'set-timezone', timezone] + subprocess.run(command, stdout=subprocess.DEVNULL, check=True) diff --git a/plinth/modules/datetime/views.py b/plinth/modules/datetime/views.py index d92848245..68c228e9e 100644 --- a/plinth/modules/datetime/views.py +++ b/plinth/modules/datetime/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring date and time. -""" +"""FreedomBox app for configuring date and time.""" import logging import pathlib @@ -9,9 +7,9 @@ import pathlib from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions from plinth.views import AppView +from . import privileged from .forms import DateTimeForm logger = logging.getLogger(__name__) @@ -19,10 +17,12 @@ logger = logging.getLogger(__name__) class DateTimeAppView(AppView): """Serve configuration page.""" + form_class = DateTimeForm app_id = 'datetime' def get_initial(self): + """Return the values to fill in the form.""" status = super().get_initial() status['time_zone'] = self.get_current_time_zone() return status @@ -35,14 +35,14 @@ class DateTimeAppView(AppView): return time_zone or 'none' def form_valid(self, form): + """Change the timezone.""" old_status = form.initial new_status = form.cleaned_data if old_status['time_zone'] != new_status['time_zone'] and \ new_status['time_zone'] != 'none': try: - actions.superuser_run('timezone-change', - [new_status['time_zone']]) + privileged.set_timezone(new_status['time_zone']) except Exception as exception: messages.error( self.request, diff --git a/plinth/modules/deluge/__init__.py b/plinth/modules/deluge/__init__.py index d6c65a743..bf4605fee 100644 --- a/plinth/modules/deluge/__init__.py +++ b/plinth/modules/deluge/__init__.py @@ -1,11 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure a Deluge web client. -""" +"""FreedomBox app to configure a Deluge web client.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import Daemon @@ -16,7 +13,7 @@ from plinth.modules.users import add_user_to_share_group from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('Deluge is a BitTorrent client that features a Web UI.'), @@ -96,5 +93,5 @@ class DelugeApp(app_module.App): """Install and configure the app.""" super().setup(old_version) add_user_to_share_group(SYSTEM_USER) - actions.superuser_run('deluge', ['setup']) + privileged.setup() self.enable() diff --git a/actions/deluge b/plinth/modules/deluge/privileged.py old mode 100755 new mode 100644 similarity index 75% rename from actions/deluge rename to plinth/modules/deluge/privileged.py index e34437e2f..d507b5a56 --- a/actions/deluge +++ b/plinth/modules/deluge/privileged.py @@ -1,11 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for BitTorrent web client. -""" +"""Configuration helper for BitTorrent web client.""" -import argparse -import json import pathlib import subprocess import time @@ -13,6 +8,7 @@ import time import augeas from plinth import action_utils +from plinth.actions import privileged from plinth.modules.deluge.utils import Config DELUGED_DEFAULT_FILE = '/etc/default/deluged' @@ -53,27 +49,6 @@ WantedBy=multi-user.target ''' # noqa: E501 -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Setup deluge') - - subparsers.add_parser('get-configuration', - help='Return the current configuration') - - subparser = subparsers.add_parser('set-configuration', - help='Set the configuration parameter') - subparser.add_argument('parameter', - help='Name of the configuration parameter') - subparser.add_argument('value', - help='Value of the configuration parameter') - - subparsers.required = True - return parser.parse_args() - - def _set_configuration(filename, parameter, value): """Set the configuration parameter.""" deluged_is_running = action_utils.service_is_running('deluged') @@ -116,25 +91,24 @@ def _set_deluged_daemon_options(): aug.save() -def subcommand_get_configuration(_): - """Return the current deluged configuration in JSON format.""" +@privileged +def get_configuration() -> dict[str, str]: + """Return the current deluged configuration.""" with Config(DELUGE_CONF_DIR / 'core.conf') as config: download_location = config.content['download_location'] - print(json.dumps({'download_location': download_location})) + return {'download_location': download_location} -def subcommand_set_configuration(arguments): +@privileged +def set_configuration(download_location: str): """Set the deluged configuration.""" - if arguments.parameter != 'download_location': - return - - _set_configuration('core.conf', arguments.parameter, arguments.value) + _set_configuration('core.conf', 'download_location', download_location) -def subcommand_setup(_): +@privileged +def setup(): """Perform initial setup for deluge.""" - with open(DELUGE_WEB_SYSTEMD_SERVICE_PATH, 'w', encoding='utf-8') as file_handle: file_handle.write(DELUGE_WEB_SYSTEMD_SERVICE) @@ -180,16 +154,3 @@ def _wait_for_configuration(service, file_name): if not is_running: action_utils.service_stop(service) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/deluge/views.py b/plinth/modules/deluge/views.py index e97b5cd7d..d8f6edc8b 100644 --- a/plinth/modules/deluge/views.py +++ b/plinth/modules/deluge/views.py @@ -1,20 +1,18 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Django views for Deluge. -""" - -import json +"""Django views for Deluge.""" from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions, views +from plinth import views +from . import privileged from .forms import DelugeForm class DelugeAppView(views.AppView): """Serve configuration page.""" + diagnostics_module_name = 'deluge' form_class = DelugeForm app_id = 'deluge' @@ -22,8 +20,7 @@ class DelugeAppView(views.AppView): def get_initial(self): """Get current Deluge server settings.""" status = super().get_initial() - configuration = json.loads( - actions.superuser_run('deluge', ['get-configuration'])) + configuration = privileged.get_configuration() status['storage_path'] = configuration['download_location'] return status @@ -33,12 +30,8 @@ class DelugeAppView(views.AppView): new_status = form.cleaned_data if old_status['storage_path'] != new_status['storage_path']: - new_configuration = [ - 'download_location', new_status['storage_path'] - ] - - actions.superuser_run('deluge', - ['set-configuration'] + new_configuration) + privileged.set_configuration( + download_location=new_status['storage_path']) messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/dynamicdns/__init__.py b/plinth/modules/dynamicdns/__init__.py index 79688396f..a6904e0c5 100644 --- a/plinth/modules/dynamicdns/__init__.py +++ b/plinth/modules/dynamicdns/__init__.py @@ -11,7 +11,6 @@ import urllib from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, glib, kvstore, menu from plinth.modules.backups.components import BackupRestore @@ -20,7 +19,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.signals import domain_added, domain_removed from plinth.utils import format_lazy -from . import gnudip, manifest +from . import gnudip, manifest, privileged logger = logging.getLogger(__name__) @@ -103,8 +102,7 @@ class DynamicDNSApp(app_module.App): self.enable() if old_version == 1: - config = actions.superuser_run('dynamicdns', ['export-config']) - config = json.loads(config) + config = privileged.export_config() if config['enabled']: self.enable() else: @@ -112,7 +110,7 @@ class DynamicDNSApp(app_module.App): del config['enabled'] set_config(config) - actions.superuser_run('dynamicdns', ['clean']) + privileged.clean() def _query_external_address(domain): diff --git a/plinth/modules/dynamicdns/privileged.py b/plinth/modules/dynamicdns/privileged.py new file mode 100644 index 000000000..79d618a33 --- /dev/null +++ b/plinth/modules/dynamicdns/privileged.py @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configuration helper for Dynamic DNS.""" + +import pathlib +import urllib + +from plinth.actions import privileged + +_conf_dir = pathlib.Path('/etc/ez-ipupdate/') +_active_config = _conf_dir / 'ez-ipupdate.conf' +_inactive_config = _conf_dir / 'ez-ipupdate.inactive' +_helper_config = _conf_dir / 'ez-ipupdate-plinth.cfg' +_cron_job = pathlib.Path('/etc/cron.d/ez-ipupdate') + + +def _read_configuration(path, separator='='): + """Read ez-ipupdate configuration.""" + config = {} + for line in path.read_text().splitlines(): + if line.startswith('#'): + continue + + parts = line.partition(separator) + if parts[1]: + config[parts[0].strip()] = parts[2].strip() + else: + config[parts[0].strip()] = True + + return config + + +@privileged +def export_config() -> dict[str, object]: + """Return the old ez-ipupdate configuration in JSON format.""" + input_config = {} + if _active_config.exists(): + input_config = _read_configuration(_active_config) + elif _inactive_config.exists(): + input_config = _read_configuration(_inactive_config) + + helper = {} + if _helper_config.exists(): + helper.update(_read_configuration(_helper_config, separator=' ')) + + def _clean(value): + value_map = {'enabled': True, 'disabled': False, '': None} + return value_map.get(value, value) + + domain = { + 'service_type': 'gnudip', + 'domain': input_config.get('host'), + 'server': input_config.get('server'), + 'username': input_config.get('user', '').split(':')[0] or None, + 'password': input_config.get('user', '').split(':')[-1] or None, + 'ip_lookup_url': helper.get('IPURL'), + 'update_url': _clean(helper.get('POSTURL')) or None, + 'use_http_basic_auth': _clean(helper.get('POSTAUTH')), + 'disable_ssl_cert_check': _clean(helper.get('POSTSSLIGNORE')), + 'use_ipv6': _clean(helper.get('POSTUSEIPV6')), + } + + if isinstance(domain['update_url'], bool): + # 'POSTURL ' is a line found in the configuration file + domain['update_url'] = None + + if not domain['server']: + domain['service_type'] = 'other' + update_url = domain['update_url'] + try: + server = urllib.parse.urlparse(update_url).netloc + service_types = { + 'dynupdate.noip.com': 'noip.com', + 'dynupdate.no-ip.com': 'noip.com', + 'freedns.afraid.org': 'freedns.afraid.org' + } + domain['service_type'] = service_types.get(server, 'other') + except ValueError: + pass + + # Old logic for 'enabling' the app is as follows: If behind NAT, add + # cronjob. If not behind NAT and type is update URL, add cronjob. If not + # behind NAT and type is GnuDIP, move inactive configuration to active + # configuration and start the ez-ipupdate daemon. + enabled = False + if _cron_job.exists() or (domain['service_type'] == 'gnudip' + and _active_config.exists()): + enabled = True + + output_config = {'enabled': enabled, 'domains': {}} + if domain['domain']: + output_config['domains'][domain['domain']] = domain + + return output_config + + +@privileged +def clean(): + """Remove all old configuration files.""" + last_update = _conf_dir / 'last-update' + status = _conf_dir / 'ez-ipupdate.status' + current_ip = _conf_dir / 'ez-ipupdate.currentIP' + + cleanup_files = [ + _active_config, _inactive_config, last_update, _helper_config, status, + current_ip + ] + for cleanup_file in cleanup_files: + try: + cleanup_file.rename(cleanup_file.with_suffix('.bak')) + except FileNotFoundError: + pass + + _cron_job.unlink(missing_ok=True) diff --git a/plinth/modules/ejabberd/__init__.py b/plinth/modules/ejabberd/__init__.py index 1e768b019..22276b5de 100644 --- a/plinth/modules/ejabberd/__init__.py +++ b/plinth/modules/ejabberd/__init__.py @@ -1,15 +1,13 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure ejabberd server. -""" +"""FreedomBox app to configure ejabberd server.""" import json import logging +from typing import Tuple from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -25,7 +23,7 @@ from plinth.signals import (domain_added, post_hostname_change, pre_hostname_change) from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('XMPP is an open and standardized communication protocol. Here ' @@ -131,14 +129,12 @@ class EjabberdApp(app_module.App): domainname = config.get_domainname() logger.info('ejabberd service domainname - %s', domainname) - actions.superuser_run('ejabberd', - ['pre-install', '--domainname', domainname]) + privileged.pre_install(domainname) # XXX: Configure all other domain names super().setup(old_version) self.get_component('letsencrypt-ejabberd').setup_certificates( [domainname]) - actions.superuser_run('ejabberd', - ['setup', '--domainname', domainname]) + privileged.setup(domainname) self.enable() # Configure STUN/TURN only if there's a valid TLS domain set for Coturn @@ -155,19 +151,14 @@ class EjabberdTurnConsumer(TurnConsumer): def on_pre_hostname_change(sender, old_hostname, new_hostname, **kwargs): - """ - Backup ejabberd database before hostname is changed. - """ + """Backup ejabberd database before hostname is changed.""" del sender # Unused del kwargs # Unused app = app_module.App.get('ejabberd') if app.needs_setup(): return - actions.superuser_run('ejabberd', [ - 'pre-change-hostname', '--old-hostname', old_hostname, - '--new-hostname', new_hostname - ]) + privileged.pre_change_hostname(old_hostname, new_hostname) def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs): @@ -178,21 +169,16 @@ def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs): if app.needs_setup(): return - actions.superuser_run('ejabberd', [ - 'change-hostname', '--old-hostname', old_hostname, '--new-hostname', - new_hostname - ], run_in_background=True) + privileged.change_hostname(_run_in_background=True) def get_domains(): - """Return the list of domains configured for ejabberd. - """ + """Return the list of domains configured for ejabberd.""" app = app_module.App.get('ejabberd') if app.needs_setup(): return [] - output = actions.superuser_run('ejabberd', ['get-domains']) - return json.loads(output) + return privileged.get_domains() def on_domain_added(sender, domain_type, name='', description='', @@ -204,7 +190,7 @@ def on_domain_added(sender, domain_type, name='', description='', domains = get_domains() if name not in domains: - actions.superuser_run('ejabberd', ['add-domain', '--domainname', name]) + privileged.add_domain(name) app.get_component('letsencrypt-ejabberd').setup_certificates() @@ -214,9 +200,7 @@ def set_domains(domains): if not domains or app.needs_setup(): return - commands = ['set-domains', '--domains'] - commands.extend(domains) - actions.superuser_run('ejabberd', commands) + privileged.set_domains(domains) app.get_component('letsencrypt-ejabberd').setup_certificates() @@ -227,14 +211,11 @@ def update_turn_configuration(config: TurnConfiguration, managed=True, if not force and app.needs_setup(): return - params = ['configure-turn'] - params += ['--managed'] if managed else [] - actions.superuser_run('ejabberd', params, input=config.to_json().encode()) + privileged.configure_turn(json.loads(config.to_json()), managed) -def get_turn_configuration() -> (TurnConfiguration, bool): +def get_turn_configuration() -> Tuple[TurnConfiguration, bool]: """Get the latest STUN/TURN configuration.""" - json_config = actions.superuser_run('ejabberd', ['get-turn-config']) - tc, managed = json.loads(json_config) - return (TurnConfiguration(tc['domain'], tc['uris'], - tc['shared_secret']), managed) + tc, managed = privileged.get_turn_config() + return TurnConfiguration(tc['domain'], tc['uris'], + tc['shared_secret']), managed diff --git a/actions/ejabberd b/plinth/modules/ejabberd/privileged.py old mode 100755 new mode 100644 similarity index 58% rename from actions/ejabberd rename to plinth/modules/ejabberd/privileged.py index 42de818f5..4e6037d1f --- a/actions/ejabberd +++ b/plinth/modules/ejabberd/privileged.py @@ -1,24 +1,23 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for the ejabberd service -""" +"""Configuration helper for the ejabberd service.""" -import argparse -import json +import logging import os import re import shutil import socket import subprocess -import sys from pathlib import Path +from typing import Any, Optional, Tuple from ruamel.yaml import YAML, scalarstring from plinth import action_utils +from plinth.actions import privileged from plinth.version import Version +logger = logging.getLogger(__name__) + EJABBERD_CONFIG = '/etc/ejabberd/ejabberd.yml' EJABBERD_BACKUP = '/var/log/ejabberd/ejabberd.dump' EJABBERD_BACKUP_NEW = '/var/log/ejabberd/ejabberd_new.dump' @@ -34,88 +33,9 @@ yaml.preserve_quotes = True TURN_URI_REGEX = r'(stun|turn):(.*):([0-9]{4})\?transport=(tcp|udp)' -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - # Get configuration - subparsers.add_parser('get-configuration', - help='Return the current configuration') - - # Preseed debconf values before packages are installed. - pre_install = subparsers.add_parser( - 'pre-install', - help='Preseed debconf values before packages are installed.') - pre_install.add_argument( - '--domainname', - help='The domain name that will be used by the XMPP service.') - - # Setup ejabberd configuration - setup = subparsers.add_parser('setup', help='Setup ejabberd configuration') - setup.add_argument( - '--domainname', - help='The domain name that will be used by the XMPP service.') - - # Prepare ejabberd for hostname change - pre_hostname_change = subparsers.add_parser( - 'pre-change-hostname', help='Prepare ejabberd for nodename change') - pre_hostname_change.add_argument('--old-hostname', - help='Previous hostname') - pre_hostname_change.add_argument('--new-hostname', help='New hostname') - - # Update ejabberd nodename - hostname_change = subparsers.add_parser('change-hostname', - help='Update ejabberd nodename') - hostname_change.add_argument('--old-hostname', help='Previous hostname') - hostname_change.add_argument('--new-hostname', help='New hostname') - - # Manage domain names - subparsers.add_parser('get-domains', - help='Get all configured domains in JSON format') - - add_domain = subparsers.add_parser('add-domain', - help='Add a domain name to ejabberd') - add_domain.add_argument('--domainname', help='New domain name') - - set_domains = subparsers.add_parser('set-domains', - help='Set list of ejabberd domains') - set_domains.add_argument('--domains', nargs='+', - help='One or more domain names') - - # Configure STUN/TURN server for use with ejabberd - turn = subparsers.add_parser( - 'configure-turn', help='Configure a TURN server for use with ejabberd') - turn.add_argument( - '--managed', required=False, default=False, action='store_true', - help='Whether configuration is provided by user or auto-managed by ' - 'FreedomBox') - - subparsers.add_parser( - 'get-turn-config', - help='Get the latest STUN/TURN configuration in JSON format') - - # Switch/check Message Archive Management (MAM) in ejabberd config - help_MAM = 'Switch or check Message Archive Management (MAM).' - mam = subparsers.add_parser('mam', help=help_MAM) - mam.add_argument('command', choices=('enable', 'disable', 'status'), - help=help_MAM) - - subparsers.required = True - return parser.parse_args() - - -def subcommand_get_configuration(_): - """Return the current configuration, specifically domains configured.""" - with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: - conf = yaml.load(file_handle) - - print(json.dumps({'domains': conf['hosts']})) - - -def subcommand_pre_install(arguments): +@privileged +def pre_install(domainname: str): """Preseed debconf values before packages are installed.""" - domainname = arguments.domainname if not domainname: # If new domainname is blank, use hostname instead. domainname = socket.gethostname() @@ -124,8 +44,9 @@ def subcommand_pre_install(arguments): ['ejabberd ejabberd/hostname string ' + domainname]) -def subcommand_setup(arguments): - """Enabled LDAP authentication""" +@privileged +def setup(domainname: str): + """Enable LDAP authentication.""" with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) @@ -143,19 +64,20 @@ def subcommand_setup(arguments): with open(EJABBERD_CONFIG, 'w', encoding='utf-8') as file_handle: yaml.dump(conf, file_handle) - upgrade_config(arguments.domainname) + _upgrade_config(domainname) try: subprocess.check_output(['ejabberdctl', 'restart']) except subprocess.CalledProcessError as err: - print('Failed to restart ejabberd with new configuration: %s', err) + logger.warn('Failed to restart ejabberd with new configuration: %s', + err) -def upgrade_config(domain): - """Fix the config file by removing deprecated settings""" +def _upgrade_config(domain): + """Fix the config file by removing deprecated settings.""" current_version = _get_version() if not current_version: - print('Warning: Unable to get ejabberd version.') + logger.warn('Warning: Unable to get ejabberd version.') with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) @@ -194,31 +116,25 @@ def upgrade_config(domain): yaml.dump(conf, file_handle) -def subcommand_pre_change_hostname(arguments): - """Prepare ejabberd for hostname change""" +@privileged +def pre_change_hostname(old_hostname: str, new_hostname: str): + """Prepare ejabberd for hostname change.""" if not shutil.which('ejabberdctl'): - print('ejabberdctl not found. Is ejabberd installed?') + logger.info('ejabberdctl not found') return - old_hostname = arguments.old_hostname - new_hostname = arguments.new_hostname - subprocess.call(['ejabberdctl', 'backup', EJABBERD_BACKUP]) - try: - subprocess.check_output([ - 'ejabberdctl', 'mnesia-change-nodename', - 'ejabberd@' + old_hostname, 'ejabberd@' + new_hostname, - EJABBERD_BACKUP, EJABBERD_BACKUP_NEW - ]) - os.remove(EJABBERD_BACKUP) - except subprocess.CalledProcessError as err: - print('Failed to change hostname in ejabberd backup database: %s', err) + subprocess.check_output([ + 'ejabberdctl', 'mnesia-change-nodename', 'ejabberd@' + old_hostname, + 'ejabberd@' + new_hostname, EJABBERD_BACKUP, EJABBERD_BACKUP_NEW + ]) + os.remove(EJABBERD_BACKUP) -def subcommand_change_hostname(arguments): - """Update ejabberd with new hostname""" +@privileged +def change_hostname(): + """Update ejabberd with new hostname.""" if not shutil.which('ejabberdctl'): - print('ejabberdctl not found. Is ejabberd installed?') return action_utils.service_stop('ejabberd') @@ -238,35 +154,34 @@ def subcommand_change_hostname(arguments): ['ejabberdctl', 'restore', EJABBERD_BACKUP_NEW]) os.remove(EJABBERD_BACKUP_NEW) except subprocess.CalledProcessError as err: - print('Failed to restore ejabberd backup database: %s', err) + logger.error('Failed to restore ejabberd backup database: %s', err) else: - print('Could not load ejabberd backup database: %s not found' % - EJABBERD_BACKUP_NEW) + logger.error('Could not load ejabberd backup database: %s not found' % + EJABBERD_BACKUP_NEW) -def subcommand_get_domains(_): +@privileged +def get_domains() -> list[str]: """Get all configured domains.""" if not shutil.which('ejabberdctl'): - print('ejabberdctl not found. Is ejabberd installed?') - return + return [] with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) - print(json.dumps(conf['hosts'])) + return conf['hosts'] -def subcommand_add_domain(arguments): +@privileged +def add_domain(domainname: str): """Update ejabberd with new domainname. Restarting ejabberd is handled by letsencrypt-ejabberd component. """ if not shutil.which('ejabberdctl'): - print('ejabberdctl not found. Is ejabberd installed?') + logger.info('ejabberdctl not found') return - domainname = arguments.domainname - # Add updated domainname to ejabberd hosts list. with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) @@ -281,43 +196,43 @@ def subcommand_add_domain(arguments): # Restarting ejabberd is handled by letsencrypt-ejabberd component. -def subcommand_set_domains(arguments): +@privileged +def set_domains(domains: list[str]): """Set list of ejabberd domains. Restarting ejabberd is handled by letsencrypt-ejabberd component. """ + if not len(domains): + raise ValueError('No domains provided') + if not shutil.which('ejabberdctl'): - print('ejabberdctl not found. Is ejabberd installed?') return with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) - conf['hosts'] = arguments.domains + conf['hosts'] = domains with open(EJABBERD_CONFIG, 'w', encoding='utf-8') as file_handle: yaml.dump(conf, file_handle) -def subcommand_mam(argument): +@privileged +def mam(command: str) -> Optional[bool]: """Enable, disable, or get status of Message Archive Management (MAM).""" + if command not in ('enable', 'disable', 'status'): + raise ValueError('Invalid command') with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) if 'modules' not in conf: - print('Found no "modules" entry in ejabberd configuration file.') - return + return None - if argument.command == 'status': - if 'mod_mam' in conf['modules']: - print('enabled') - return - else: - print('disabled') - return + if command == 'status': + return 'mod_mam' in conf['modules'] - if argument.command == 'enable': + if command == 'enable': # Explicitly set the recommended / default settings for mod_mam, # see https://docs.ejabberd.im/admin/configuration/#mod-mam. settings_mod_mam = { @@ -332,13 +247,10 @@ def subcommand_mam(argument): } } conf['modules'].update(settings_mod_mam) - elif argument.command == 'disable': + elif command == 'disable': # disable modules by erasing from config file if 'mod_mam' in conf['modules']: conf['modules'].pop('mod_mam') - else: - print("Unknown command: %s" % argument.command) - return with open(EJABBERD_CONFIG, 'w', encoding='utf-8') as file_handle: yaml.dump(conf, file_handle) @@ -346,6 +258,8 @@ def subcommand_mam(argument): if action_utils.service_is_running('ejabberd'): subprocess.call(['ejabberdctl', 'reload_config']) + return None + def _generate_service(uri: str) -> dict: """Generate ejabberd mod_stun_disco service config from Coturn URI.""" @@ -368,7 +282,8 @@ def _generate_uris(services: list[dict]) -> list[str]: ] -def subcommand_get_turn_config(_): +@privileged +def get_turn_config() -> Tuple[dict[str, Any], bool]: """Get the latest STUN/TURN configuration in JSON format.""" with open(EJABBERD_CONFIG, 'r', encoding='utf-8') as file_handle: conf = yaml.load(file_handle) @@ -377,24 +292,18 @@ def subcommand_get_turn_config(_): managed = os.path.exists(EJABBERD_MANAGED_COTURN) if bool(mod_stun_disco_config): - print( - json.dumps([{ - 'domain': '', - 'uris': _generate_uris(mod_stun_disco_config['services']), - 'shared_secret': mod_stun_disco_config['secret'], - }, managed])) + return { + 'domain': '', + 'uris': _generate_uris(mod_stun_disco_config['services']), + 'shared_secret': mod_stun_disco_config['secret'], + }, managed else: - print( - json.dumps([{ - 'domain': None, - 'uris': [], - 'shared_secret': None - }, managed])) + return {'domain': None, 'uris': [], 'shared_secret': None}, managed -def subcommand_configure_turn(arguments): +@privileged +def configure_turn(turn_server_config: dict[str, Any], managed: bool): """Set parameters for the STUN/TURN server to use with ejabberd.""" - turn_server_config = json.loads(''.join(sys.stdin)) uris = turn_server_config['uris'] mod_stun_disco_config = {} @@ -413,7 +322,7 @@ def subcommand_configure_turn(arguments): with open(EJABBERD_CONFIG, 'w', encoding='utf-8') as file_handle: yaml.dump(conf, file_handle) - if arguments.managed: + if managed: Path(EJABBERD_MANAGED_COTURN).touch() else: Path(EJABBERD_MANAGED_COTURN).unlink(missing_ok=True) @@ -423,7 +332,7 @@ def subcommand_configure_turn(arguments): def _get_version(): - """ Get the current ejabberd version """ + """Get the current ejabberd version.""" try: output = subprocess.check_output(['ejabberdctl', 'status']).decode('utf-8') @@ -435,16 +344,3 @@ def _get_version(): version = str(version_info[1]) return Version(version) return None - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/ejabberd/tests/test_turn_config.py b/plinth/modules/ejabberd/tests/test_turn_config.py index 055a01db5..f88618c47 100644 --- a/plinth/modules/ejabberd/tests/test_turn_config.py +++ b/plinth/modules/ejabberd/tests/test_turn_config.py @@ -11,6 +11,7 @@ import pytest from plinth.modules import ejabberd from plinth.modules.coturn.components import TurnConfiguration +from plinth.modules.ejabberd import privileged managed_configuration = TurnConfiguration( 'freedombox.local', [], @@ -20,9 +21,9 @@ overridden_configuration = TurnConfiguration( 'public.coturn.site', [], 'BUeKvKzhAsTZ8MEwMd3yTwpr2uvbOxgWe51aiP02OAGyOlj6WGuCyqj7iaOsbkC7') -actions_name = 'ejabberd' - +pytestmark = pytest.mark.usefixtures('mock_privileged') current_directory = pathlib.Path(__file__).parent +privileged_modules_to_mock = ['plinth.modules.ejabberd.privileged'] @pytest.fixture(name='conf_file') @@ -45,30 +46,26 @@ def fixture_managed_file(tmp_path): @pytest.fixture(autouse=True) -def fixture_set_configuration_paths(actions_module, conf_file, managed_file): +def fixture_set_configuration_paths(conf_file, managed_file): """Setup configuration file paths in action module.""" - actions_module.EJABBERD_CONFIG = conf_file - actions_module.EJABBERD_MANAGED_COTURN = managed_file + privileged.EJABBERD_CONFIG = conf_file + privileged.EJABBERD_MANAGED_COTURN = managed_file @pytest.fixture(name='test_configuration', autouse=True) -def fixture_test_configuration(call_action, conf_file): +def fixture_test_configuration(conf_file): """Use a separate ejabberd configuration for tests. - Patches actions.superuser_run with the fixture call_action. The module state is patched to be 'up-to-date'. """ - with patch('plinth.actions.superuser_run', - call_action), patch('plinth.app.App.get') as app_get: + with patch('plinth.app.App.get') as app_get: app = Mock() app_get.return_value = app app.needs_setup.return_value = False yield -def _set_turn_configuration(monkeypatch, config=managed_configuration, - managed=True): - monkeypatch.setattr('sys.stdin', config.to_json()) +def _set_turn_configuration(config=managed_configuration, managed=True): with patch('plinth.action_utils.service_is_running', return_value=False): ejabberd.update_turn_configuration(config, managed=managed) @@ -81,17 +78,17 @@ def _assert_conf(expected_configuration, expected_managed): assert managed == expected_managed -def test_managed_turn_server_configuration(monkeypatch): - _set_turn_configuration(monkeypatch) +def test_managed_turn_server_configuration(): + _set_turn_configuration() _assert_conf(managed_configuration, True) -def test_overridden_turn_server_configuration(monkeypatch): - _set_turn_configuration(monkeypatch, overridden_configuration, False) +def test_overridden_turn_server_configuration(): + _set_turn_configuration(overridden_configuration, False) _assert_conf(overridden_configuration, False) -def test_remove_turn_configuration(monkeypatch): - _set_turn_configuration(monkeypatch) - _set_turn_configuration(monkeypatch, TurnConfiguration(), False) +def test_remove_turn_configuration(): + _set_turn_configuration() + _set_turn_configuration(TurnConfiguration(), False) _assert_conf(TurnConfiguration(), False) diff --git a/plinth/modules/ejabberd/views.py b/plinth/modules/ejabberd/views.py index cca1b102b..eb01d2b1f 100644 --- a/plinth/modules/ejabberd/views.py +++ b/plinth/modules/ejabberd/views.py @@ -1,31 +1,30 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the Ejabberd module -""" +"""Views for the Ejabberd app.""" from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions from plinth.modules import coturn, ejabberd from plinth.modules.coturn.components import TurnConfiguration from plinth.views import AppView +from . import privileged from .forms import EjabberdForm class EjabberdAppView(AppView): """Show ejabberd as a service.""" + app_id = 'ejabberd' template_name = 'ejabberd.html' form_class = EjabberdForm def get_initial(self): - """Initial data to fill in the form.""" + """Return initial data to fill in the form.""" config, managed = ejabberd.get_turn_configuration() return super().get_initial() | { 'domain_names': ejabberd.get_domains(), - 'MAM_enabled': self.is_MAM_enabled(), + 'MAM_enabled': privileged.mam('status'), 'enable_managed_turn': managed, 'turn_uris': '\n'.join(config.uris), 'shared_secret': config.shared_secret @@ -65,9 +64,9 @@ class EjabberdAppView(AppView): def _handle_MAM_configuration(old_config, new_config): # note ejabberd action "enable" or "disable" restarts, if running if new_config['MAM_enabled']: - actions.superuser_run('ejabberd', ['mam', 'enable']) + privileged.mam('enable') else: - actions.superuser_run('ejabberd', ['mam', 'disable']) + privileged.mam('disable') def form_valid(self, form): """Enable/disable a service and set messages.""" @@ -96,8 +95,3 @@ class EjabberdAppView(AppView): messages.success(self.request, _('Configuration updated')) return super().form_valid(form) - - def is_MAM_enabled(self): - """Return whether Message Archive Management (MAM) is enabled.""" - output = actions.superuser_run('ejabberd', ['mam', 'status']) - return output.strip() == 'enabled' diff --git a/plinth/modules/email/__init__.py b/plinth/modules/email/__init__.py index 2f9236af0..03e2564dd 100644 --- a/plinth/modules/email/__init__.py +++ b/plinth/modules/email/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to manage an email server. -""" +"""FreedomBox app to manage an email server.""" import logging @@ -9,7 +7,7 @@ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ import plinth.app -from plinth import actions, cfg, frontpage, menu +from plinth import cfg, frontpage, menu from plinth.daemon import Daemon from plinth.modules.apache.components import Webserver from plinth.modules.backups.components import BackupRestore @@ -17,6 +15,7 @@ from plinth.modules.config import get_domainname from plinth.modules.firewall.components import Firewall from plinth.modules.letsencrypt.components import LetsEncrypt from plinth.package import Packages, uninstall +from plinth.privileged import service as service_privileged from plinth.signals import domain_added, domain_removed from plinth.utils import format_lazy @@ -49,12 +48,13 @@ logger = logging.getLogger(__name__) class EmailApp(plinth.app.App): """FreedomBox app for an email server.""" + app_id = 'email' _version = 1 def __init__(self): - """The app's constructor""" + """Initialize the email app.""" super().__init__() info = plinth.app.Info(app_id=self.app_id, version=self._version, @@ -180,18 +180,19 @@ class EmailApp(plinth.app.App): super().setup(old_version) # Setup - privileged.home.setup() + privileged.setup_home() self.get_component('letsencrypt-email-postfix').setup_certificates() self.get_component('letsencrypt-email-dovecot').setup_certificates() - privileged.domain.set_domains() - privileged.postfix.setup() + privileged.domain.set_all_domains() + aliases.first_setup() + privileged.setup_postfix() aliases.setup_common_aliases(_get_first_admin()) - privileged.spam.setup() + privileged.setup_spam() # Restart daemons - actions.superuser_run('service', ['try-restart', 'postfix']) - actions.superuser_run('service', ['try-restart', 'dovecot']) - actions.superuser_run('service', ['try-restart', 'rspamd']) + service_privileged.try_restart('postfix') + service_privileged.try_restart('dovecot') + service_privileged.try_restart('rspamd') # Expose to public internet if old_version == 0: @@ -218,7 +219,7 @@ def on_domain_added(sender, domain_type, name, description='', services=None, if app.needs_setup(): return - privileged.domain.set_domains() + privileged.domain.set_all_domains() def on_domain_removed(sender, domain_type, name='', **kwargs): @@ -227,4 +228,4 @@ def on_domain_removed(sender, domain_type, name='', **kwargs): if app.needs_setup(): return - privileged.domain.set_domains() + privileged.domain.set_all_domains() diff --git a/plinth/modules/email/aliases.py b/plinth/modules/email/aliases.py index 5d5b3fec8..425f63bd9 100644 --- a/plinth/modules/email/aliases.py +++ b/plinth/modules/email/aliases.py @@ -1,14 +1,12 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Manage email aliases stored in sqlite database. -""" +"""Manage email aliases stored in sqlite database.""" import contextlib import pwd import sqlite3 from dataclasses import dataclass -from plinth import actions +from . import privileged @dataclass @@ -75,7 +73,7 @@ def delete(username, aliases): def first_setup(): """Create the database file and schema inside it.""" - actions.superuser_run('email', ['aliases', 'setup']) + privileged.aliases.setup_aliases() # Create schema if not exists query = ''' diff --git a/plinth/modules/email/dns.py b/plinth/modules/email/dns.py index c6df85abe..fecd051b7 100644 --- a/plinth/modules/email/dns.py +++ b/plinth/modules/email/dns.py @@ -12,12 +12,11 @@ See: https://rspamd.com/doc/modules/dkim_signing.html from dataclasses import dataclass from typing import Union -from plinth.errors import ActionError - @dataclass class Entry: # pylint: disable=too-many-instance-attributes """A DNS entry.""" + type_: str value: str domain: Union[str, None] = None @@ -55,12 +54,12 @@ def get_entries(): f'rua=mailto:postmaster@{domain}; ') ] try: - dkim_public_key = privileged.dkim.get_public_key(domain) + dkim_public_key = privileged.get_dkim_public_key(domain) dkim_entries = [ Entry(domain='dkim._domainkey', type_='TXT', value=f'v=DKIM1; k=rsa; p={dkim_public_key}') ] - except ActionError: + except Exception: dkim_entries = [] autoconfig_entries = [ diff --git a/plinth/modules/email/privileged/__init__.py b/plinth/modules/email/privileged/__init__.py index 8591aa98c..cf5e8ea28 100644 --- a/plinth/modules/email/privileged/__init__.py +++ b/plinth/modules/email/privileged/__init__.py @@ -1,8 +1,14 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Provides privileged actions that run as root. -""" +"""Provides privileged actions that run as root.""" -from . import aliases, dkim, domain, home, postfix, spam, tls +from .aliases import setup_aliases +from .dkim import get_dkim_public_key, setup_dkim +from .domain import set_domains +from .home import setup_home +from .postfix import setup_postfix +from .spam import setup_spam -__all__ = ['aliases', 'domain', 'dkim', 'home', 'postfix', 'spam', 'tls'] +__all__ = [ + 'setup_aliases', 'get_dkim_public_key', 'setup_dkim', 'set_domains', + 'setup_home', 'setup_postfix', 'setup_spam' +] diff --git a/plinth/modules/email/privileged/aliases.py b/plinth/modules/email/privileged/aliases.py index 78e4ea62b..208a622b9 100644 --- a/plinth/modules/email/privileged/aliases.py +++ b/plinth/modules/email/privileged/aliases.py @@ -1,13 +1,14 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Privileged operations for managing aliases. -""" +"""Privileged operations for managing aliases.""" import pathlib import shutil +from plinth.actions import privileged -def action_setup(): + +@privileged +def setup_aliases(): """Create a the sqlite3 database to be managed by FreedomBox.""" path = pathlib.Path('/var/lib/postfix/freedombox-aliases/') path.mkdir(mode=0o750, exist_ok=True) diff --git a/plinth/modules/email/privileged/dkim.py b/plinth/modules/email/privileged/dkim.py index 95a413e8e..f57ba47fb 100644 --- a/plinth/modules/email/privileged/dkim.py +++ b/plinth/modules/email/privileged/dkim.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Generate DKIM keys for signing outgoing messages. +"""Generate DKIM keys for signing outgoing messages. See: https://rspamd.com/doc/modules/dkim_signing.html """ @@ -10,7 +9,7 @@ import re import shutil import subprocess -from plinth import actions +from plinth.actions import privileged _keys_dir = pathlib.Path('/var/lib/rspamd/dkim/') @@ -23,24 +22,19 @@ def _validate_domain_name(domain): raise ValueError('Invalid domain name') -def get_public_key(domain): - """Return the DKIM public key for the given domain.""" - output = actions.superuser_run('email', - ['dkim', 'get_dkim_public_key', domain]) - return output.strip() - - -def action_get_dkim_public_key(domain): +@privileged +def get_dkim_public_key(domain: str) -> str: """Privileged action to get the public key from DKIM key.""" _validate_domain_name(domain) key_file = _keys_dir / f'{domain}.dkim.key' output = subprocess.check_output( ['openssl', 'rsa', '-in', str(key_file), '-pubout'], stderr=subprocess.DEVNULL) - print(''.join(output.decode().splitlines()[1:-1])) + return ''.join(output.decode().splitlines()[1:-1]) -def action_setup_dkim(domain): +@privileged +def setup_dkim(domain: str): """Create DKIM key for a given domain.""" _validate_domain_name(domain) diff --git a/plinth/modules/email/privileged/domain.py b/plinth/modules/email/privileged/domain.py index 10176933c..d8a792956 100644 --- a/plinth/modules/email/privileged/domain.py +++ b/plinth/modules/email/privileged/domain.py @@ -10,13 +10,13 @@ See: http://www.postfix.org/postconf.5.html#myhostname import pathlib import re -from plinth.actions import superuser_run +from plinth.actions import privileged from plinth.app import App from plinth.modules import config from plinth.modules.email import postfix from plinth.modules.names.components import DomainName -from . import tls +from . import dkim, tls def get_domains(): @@ -28,7 +28,7 @@ def get_domains(): return {'primary_domain': conf['mydomain'], 'all_domains': domains} -def set_domains(primary_domain=None): +def set_all_domains(primary_domain=None): """Set the primary domain and all the domains for postfix.""" all_domains = DomainName.list_names() if not primary_domain: @@ -37,10 +37,8 @@ def set_domains(primary_domain=None): primary_domain = config.get_domainname() or list(all_domains)[0] # Update configuration and don't restart daemons - superuser_run( - 'email', - ['domain', 'set_domains', primary_domain, ','.join(all_domains)]) - superuser_run('email', ['dkim', 'setup_dkim', primary_domain]) + set_domains(primary_domain, list(all_domains)) + dkim.setup_dkim(primary_domain) # Copy certificates (self-signed if needed) and restart daemons app = App.get('email') @@ -48,9 +46,10 @@ def set_domains(primary_domain=None): app.get_component('letsencrypt-email-dovecot').setup_certificates() -def action_set_domains(primary_domain, all_domains): +@privileged +def set_domains(primary_domain: str, all_domains: list[str]): """Set the primary domain and all the domains for postfix.""" - all_domains = [_clean_domain(domain) for domain in all_domains.split(',')] + all_domains = [_clean_domain(domain) for domain in all_domains] primary_domain = _clean_domain(primary_domain) defaults = {'$myhostname', 'localhost.$mydomain', 'localhost'} diff --git a/plinth/modules/email/privileged/home.py b/plinth/modules/email/privileged/home.py index 37d9ff2b4..544643dc3 100644 --- a/plinth/modules/email/privileged/home.py +++ b/plinth/modules/email/privileged/home.py @@ -8,20 +8,15 @@ https://doc.dovecot.org/configuration_manual/authentication/user_databases_userd import subprocess -from plinth import actions +from plinth.actions import privileged -def setup(): +@privileged +def setup_home(): """Set correct permissions on /var/mail/ directory. For each user, /var/mail/ is the 'dovecot mail home' for that user. Dovecot creates new directories with the same permissions as the parent - directory. Ensure that 'others' can access /var/mail/. - + directory. Ensure that 'others' can't access /var/mail/. """ - actions.superuser_run('email', ['home', 'setup']) - - -def action_setup(): - """Run chmod on /var/mail to remove all permissions for 'others'.""" subprocess.run(['chmod', 'o-rwx', '/var/mail'], check=True) diff --git a/plinth/modules/email/privileged/postfix.py b/plinth/modules/email/privileged/postfix.py index 9b42d6a50..be479c440 100644 --- a/plinth/modules/email/privileged/postfix.py +++ b/plinth/modules/email/privileged/postfix.py @@ -1,7 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configure postfix to use auth and local delivery with dovecot. Start smtps and -submission services. Setup aliases database. +"""Configure postix. + +- Configure postfix to use auth and local delivery with dovecot. +- Start SMTPS and submission services. Setup aliases database. See: https://doc.dovecot.org/configuration_manual/howto/postfix_and_dovecot_sasl/ @@ -9,9 +10,8 @@ See: https://doc.dovecot.org/configuration_manual/howto/postfix_dovecot_lmtp/ See: http://www.postfix.org/TLS_README.html """ -from plinth import actions +from plinth.actions import privileged -from .. import aliases from .. import postfix as postconf default_config = { @@ -57,13 +57,9 @@ smtps_service = postconf.Service(service='smtps', type_='inet', private='n', SQLITE_ALIASES = 'sqlite:/etc/postfix/freedombox-aliases.cf' -def setup(): - """Set SASL, mail submission, and user lookup settings.""" - aliases.first_setup() - actions.superuser_run('email', ['postfix', 'setup']) - - -def action_setup(): +@privileged +def setup_postfix(): + """Configure postfix.""" postconf.set_config(default_config) _setup_submission() _setup_alias_maps() diff --git a/plinth/modules/email/privileged/spam.py b/plinth/modules/email/privileged/spam.py index a2f8bbc8d..046a2b508 100644 --- a/plinth/modules/email/privileged/spam.py +++ b/plinth/modules/email/privileged/spam.py @@ -10,7 +10,7 @@ import pathlib import re import subprocess -from plinth import actions +from plinth.actions import privileged from plinth.modules.email import postfix _milter_config = { @@ -19,12 +19,8 @@ _milter_config = { } -def setup(): - """Trigger a privileged setup action.""" - actions.superuser_run('email', ['spam', 'setup']) - - -def action_setup(): +@privileged +def setup_spam(): """Compile sieve filters and set rspamd/postfix configuration.""" _compile_sieve() _setup_rspamd() diff --git a/plinth/modules/email/views.py b/plinth/modules/email/views.py index 70d8b4dd2..bac67c3b2 100644 --- a/plinth/modules/email/views.py +++ b/plinth/modules/email/views.py @@ -41,7 +41,7 @@ class EmailAppView(AppView): new_data = form.cleaned_data if old_data['primary_domain'] != new_data['primary_domain']: try: - privileged.domain.set_domains(new_data['primary_domain']) + privileged.domain.set_all_domains(new_data['primary_domain']) messages.success(self.request, _('Configuration updated')) except Exception: messages.error(self.request, diff --git a/plinth/modules/firewall/__init__.py b/plinth/modules/firewall/__init__.py index 8b4dc11f2..9603b8f06 100644 --- a/plinth/modules/firewall/__init__.py +++ b/plinth/modules/firewall/__init__.py @@ -1,14 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure a firewall. -""" +"""FreedomBox app to configure a firewall.""" import contextlib import logging from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu from plinth.daemon import Daemon @@ -16,7 +13,7 @@ from plinth.modules.backups.components import BackupRestore from plinth.package import Packages, install from plinth.utils import Version, format_lazy, import_from_gi -from . import manifest +from . import manifest, privileged gio = import_from_gi('Gio', '2.0') glib = import_from_gi('GLib', '2.0') @@ -98,7 +95,7 @@ class FirewallApp(app_module.App): def _run_setup(): """Run firewalld setup.""" - _run(['setup'], superuser=True) + privileged.setup() add_service('http', 'external') add_service('http', 'internal') add_service('https', 'external') @@ -171,17 +168,8 @@ def try_with_reload(operation): operation() -def get_enabled_status(): - """Return whether firewall is enabled""" - output = _run(['get-status'], superuser=True) - if not output: - return False - else: - return output.split()[0] == 'running' - - def get_enabled_services(zone): - """Return the status of various services currently enabled""" + """Return the status of various services currently enabled.""" with ignore_dbus_error(dbus_error='ServiceUnknown'): zone_proxy = _get_dbus_proxy(_FIREWALLD_OBJECT, _ZONE_INTERFACE) return zone_proxy.getServices('(s)', zone) @@ -190,7 +178,7 @@ def get_enabled_services(zone): def get_port_details(service_port): - """Return the port types and numbers for a service port""" + """Return the port types and numbers for a service port.""" try: return _port_details[service_port] except KeyError: @@ -215,7 +203,7 @@ def get_interfaces(zone): def add_service(port, zone): - """Enable a service in firewall""" + """Enable a service in firewall.""" with ignore_dbus_error(dbus_error='ServiceUnknown'): zone_proxy = _get_dbus_proxy(_FIREWALLD_OBJECT, _ZONE_INTERFACE) with ignore_dbus_error(service_error='ALREADY_ENABLED'): @@ -229,7 +217,7 @@ def add_service(port, zone): def remove_service(port, zone): - """Remove a service in firewall""" + """Remove a service in firewall.""" with ignore_dbus_error(dbus_error='ServiceUnknown'): zone_proxy = _get_dbus_proxy(_FIREWALLD_OBJECT, _ZONE_INTERFACE) with ignore_dbus_error(service_error='NOT_ENABLED'): @@ -240,13 +228,3 @@ def remove_service(port, zone): config_zone = _get_dbus_proxy(zone_path, _CONFIG_ZONE_INTERFACE) with ignore_dbus_error(service_error='NOT_ENABLED'): config_zone.removeService('(s)', port) - - -def _run(arguments, superuser=False): - """Run an given command and raise exception if there was an error""" - command = 'firewall' - - if superuser: - return actions.superuser_run(command, arguments) - else: - return actions.run(command, arguments) diff --git a/actions/firewall b/plinth/modules/firewall/privileged.py old mode 100755 new mode 100644 similarity index 66% rename from actions/firewall rename to plinth/modules/firewall/privileged.py index 68263087c..56592cdc1 --- a/actions/firewall +++ b/plinth/modules/firewall/privileged.py @@ -1,31 +1,12 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for FreedomBox firewall interface. -""" +"""Configuration helper for FreedomBox firewall interface.""" -import argparse import subprocess import augeas from plinth import action_utils - - -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - # Setup - subparsers.add_parser('setup', help='Perform basic firewall setup') - - # Get status - subparsers.add_parser('get-status', - help='Get whether firewalld is running') - - subparsers.required = True - return parser.parse_args() +from plinth.actions import privileged def _flush_iptables_rules(): @@ -81,26 +62,11 @@ def set_firewall_backend(backend): action_utils.service_restart('firewalld') -def subcommand_setup(_): +@privileged +def setup(): """Perform basic firewalld setup.""" action_utils.service_enable('firewalld') - subprocess.call(['firewall-cmd', '--set-default-zone=external']) + subprocess.run(['firewall-cmd', '--set-default-zone=external'], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, + check=True) set_firewall_backend('nftables') - - -def subcommand_get_status(_): - """Print status of the firewalld service""" - subprocess.call(['firewall-cmd', '--state']) - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == "__main__": - main() diff --git a/plinth/modules/firewall/templates/firewall.html b/plinth/modules/firewall/templates/firewall.html index e87d4618c..a9dc0eb9d 100644 --- a/plinth/modules/firewall/templates/firewall.html +++ b/plinth/modules/firewall/templates/firewall.html @@ -15,97 +15,82 @@

{% trans "Status" %}

- {% if firewall_status == 'not_running' %} +
+ + + + + -

- {% blocktrans trimmed %} - Firewall daemon is not running. Please run it. Firewall comes - enabled by default on {{ box_name }}. On any Debian based - system (such as {{ box_name }}) you may run it using the - command 'service firewalld start' or in case of a system with - systemd 'systemctl start firewalld'. - {% endblocktrans %} -

- - {% else %} - -
-
{% trans "Service/Port" %}{% trans "Status" %}
- - - - - - - {% for component in components|dictsort:"name" %} - {% if component.ports %} - - + {% for component in components|dictsort:"name" %} + {% if component.ports %} + + + + + {% for port in component.ports_details %} + + - - {% for port in component.ports_details %} - - - - - {% endfor %} - {% endif %} - {% endfor %} - -
{% trans "Service/Port" %}{% trans "Status" %}
- +
+ + + {% if component.is_enabled %} + + {% trans "Enabled" %} + {% else %} + + {% trans "Disabled" %} + {% endif %} +
+ {{ port.name }}: + {% for port_number, protocol in port.details %} + {{ port_number }}/{{ protocol }} + {% endfor %} - {% if component.is_enabled %} + + {% if port.name in internal_enabled_ports and port.name in external_enabled_ports %} - {% trans "Enabled" %} - {% else %} + {% trans "Permitted" %} + {% elif port.name in internal_enabled_ports %} - {% trans "Disabled" %} + {% trans "Permitted (internal only)" %} + {% elif port.name in external_enabled_ports %} + + {% trans "Permitted (external only)" %} + {% else %} + + {% trans "Blocked" %} {% endif %}
- {{ port.name }}: - {% for port_number, protocol in port.details %} - {{ port_number }}/{{ protocol }} - {% endfor %} - - {% if port.name in internal_enabled_ports and port.name in external_enabled_ports %} - - {% trans "Permitted" %} - {% elif port.name in internal_enabled_ports %} - - {% trans "Permitted (internal only)" %} - {% elif port.name in external_enabled_ports %} - - {% trans "Permitted (external only)" %} - {% else %} - - {% trans "Blocked" %} - {% endif %} -
-
+ {% endfor %} + {% endif %} + {% endfor %} + + + -

- - {% blocktrans trimmed %} - The operation of the firewall is automatic. When you enable - a service it is also permitted in the firewall and when you - disable a service it is also disabled in the firewall. - {% endblocktrans %} - -

- -

{%trans "Advanced" %}

-

+

+ {% blocktrans trimmed %} - Advanced firewall operations such as opening custom ports are provided - by the Cockpit app. + The operation of the firewall is automatic. When you enable + a service it is also permitted in the firewall and when you + disable a service it is also disabled in the firewall. {% endblocktrans %} -

- {% endif %} + +

+ +

{%trans "Advanced" %}

+

+ {% blocktrans trimmed %} + Advanced firewall operations such as opening custom ports are provided + by the Cockpit app. + {% endblocktrans %} +

{% endblock %} diff --git a/plinth/modules/firewall/views.py b/plinth/modules/firewall/views.py index c517a231a..69fc1d366 100644 --- a/plinth/modules/firewall/views.py +++ b/plinth/modules/firewall/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure a firewall. -""" +"""FreedomBox app to configure a firewall.""" from plinth import views from plinth.modules import firewall @@ -11,23 +9,16 @@ from . import components class FirewallAppView(views.AppView): """Serve firewall index page.""" + app_id = 'firewall' template_name = 'firewall.html' def get_context_data(self, *args, **kwargs): """Add additional context data for the template.""" context = super().get_context_data(*args, **kwargs) - - status = 'running' if firewall.get_enabled_status() else 'not_running' - context['firewall_status'] = status - - if status == 'running': - context['components'] = components.Firewall.list() - internal_enabled_ports = firewall.get_enabled_services( - zone='internal') - external_enabled_ports = firewall.get_enabled_services( - zone='external') - context['internal_enabled_ports'] = internal_enabled_ports - context['external_enabled_ports'] = external_enabled_ports - + context['components'] = components.Firewall.list() + internal_enabled_ports = firewall.get_enabled_services(zone='internal') + external_enabled_ports = firewall.get_enabled_services(zone='external') + context['internal_enabled_ports'] = internal_enabled_ports + context['external_enabled_ports'] = external_enabled_ports return context diff --git a/plinth/modules/gitweb/__init__.py b/plinth/modules/gitweb/__init__.py index f6e958377..ead2bdc3b 100644 --- a/plinth/modules/gitweb/__init__.py +++ b/plinth/modules/gitweb/__init__.py @@ -1,24 +1,19 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Gitweb. -""" +"""FreedomBox app to configure Gitweb.""" -import json import os from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu -from plinth.errors import ActionError from plinth.modules.apache.components import Webserver from plinth.modules.backups.components import BackupRestore from plinth.modules.firewall.components import Firewall from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages -from . import manifest +from . import manifest, privileged from .forms import is_repo_url from .manifest import GIT_REPO_PATH @@ -129,7 +124,7 @@ class GitwebApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('gitweb', ['setup']) + privileged.setup() self.enable() @@ -161,36 +156,31 @@ class GitwebBackupRestore(BackupRestore): self.app.update_service_access() -def repo_exists(name): - """Check whether a remote repository exists.""" - try: - actions.run('gitweb', ['check-repo-exists', '--url', name]) - except ActionError: - return False - - return True - - def have_public_repos(repos): - """Check for public repositories""" + """Check for public repositories.""" return any((repo['access'] == 'public' for repo in repos)) def create_repo(repo, repo_description, owner, is_private): """Create a new repository or clone a remote repository.""" - args = ['--description', repo_description, '--owner', owner] - if is_private: - args.append('--is-private') + kwargs = { + 'url': None, + 'name': None, + 'description': repo_description, + 'owner': owner, + 'is_private': is_private + } + if is_repo_url(repo): - args = ['create-repo', '--url', repo] + args + kwargs['url'] = repo # create a repo directory and set correct access rights - actions.superuser_run('gitweb', args + ['--prepare-only']) + privileged.create_repo(prepare_only=True, **kwargs) # start cloning in background - actions.superuser_run('gitweb', args + ['--skip-prepare'], - run_in_background=True) + privileged.create_repo(skip_prepare=True, _run_in_background=True, + **kwargs) else: - args = ['create-repo', '--name', repo] + args - actions.superuser_run('gitweb', args) + kwargs['name'] = repo + privileged.create_repo(**kwargs) def get_repo_list(): @@ -223,8 +213,7 @@ def get_repo_list(): def repo_info(repo): """Get information about repository.""" - output = actions.run('gitweb', ['repo-info', '--name', repo]) - info = json.loads(output) + info = privileged.repo_info(repo) if info['access'] == 'private': info['is_private'] = True else: @@ -234,72 +223,25 @@ def repo_info(repo): return info -def _rename_repo(oldname, newname): - """Rename a repository.""" - args = ['rename-repo', '--oldname', oldname, '--newname', newname] - actions.superuser_run('gitweb', args) - - -def _set_default_branch(repo, branch): - """Set default branch of the repository.""" - args = [ - 'set-default-branch', - '--name', - repo, - '--branch', - branch, - ] - actions.superuser_run('gitweb', args) - - -def _set_repo_description(repo, repo_description): - """Set description of the repository.""" - args = [ - 'set-repo-description', - '--name', - repo, - '--description', - repo_description, - ] - actions.superuser_run('gitweb', args) - - -def _set_repo_owner(repo, owner): - """Set repository's owner name.""" - args = ['set-repo-owner', '--name', repo, '--owner', owner] - actions.superuser_run('gitweb', args) - - -def _set_repo_access(repo, access): - """Set repository's owner name.""" - args = ['set-repo-access', '--name', repo, '--access', access] - actions.superuser_run('gitweb', args) - - def edit_repo(form_initial, form_cleaned): """Edit repository data.""" repo = form_initial['name'] if form_cleaned['name'] != repo: - _rename_repo(repo, form_cleaned['name']) + privileged.rename_repo(repo, form_cleaned['name']) repo = form_cleaned['name'] if form_cleaned['description'] != form_initial['description']: - _set_repo_description(repo, form_cleaned['description']) + privileged.set_repo_description(repo, form_cleaned['description']) if form_cleaned['owner'] != form_initial['owner']: - _set_repo_owner(repo, form_cleaned['owner']) + privileged.set_repo_owner(repo, form_cleaned['owner']) if form_cleaned['is_private'] != form_initial['is_private']: if form_cleaned['is_private']: - _set_repo_access(repo, 'private') + privileged.set_repo_access(repo, 'private') else: - _set_repo_access(repo, 'public') + privileged.set_repo_access(repo, 'public') if form_cleaned['default_branch'] != form_initial['default_branch']: - _set_default_branch(repo, form_cleaned['default_branch']) - - -def delete_repo(repo): - """Delete a repository.""" - actions.superuser_run('gitweb', ['delete-repo', '--name', repo]) + privileged.set_default_branch(repo, form_cleaned['default_branch']) diff --git a/plinth/modules/gitweb/forms.py b/plinth/modules/gitweb/forms.py index 555f8918b..76ba8a314 100644 --- a/plinth/modules/gitweb/forms.py +++ b/plinth/modules/gitweb/forms.py @@ -3,7 +3,6 @@ Django form for configuring Gitweb. """ -import json import re from urllib.parse import urlparse @@ -12,14 +11,14 @@ from django.core.exceptions import ValidationError from django.core.validators import URLValidator from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth.modules import gitweb +from . import privileged + def _get_branches(repo): """Get all the branches in the repository.""" - branch_data = json.loads( - actions.run('gitweb', ['get-branches', '--name', repo])) + branch_data = privileged.get_branches(repo) default_branch = branch_data['default_branch'] branches = branch_data['branches'] @@ -113,7 +112,7 @@ class CreateRepoForm(forms.Form): _('A repository with this name already exists.')) if is_repo_url(name): - if not gitweb.repo_exists(name): + if not privileged.repo_exists(name): raise ValidationError('Remote repository is not available.') return name diff --git a/actions/gitweb b/plinth/modules/gitweb/privileged.py old mode 100755 new mode 100644 similarity index 50% rename from actions/gitweb rename to plinth/modules/gitweb/privileged.py index 124e55650..3bb213eed --- a/actions/gitweb +++ b/plinth/modules/gitweb/privileged.py @@ -1,145 +1,40 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Gitweb. -""" +"""Configuration helper for Gitweb.""" -import argparse import configparser -import json import logging import os import re import shutil import subprocess -import sys import time +from typing import Any, Optional from plinth import action_utils +from plinth.actions import privileged from plinth.modules.gitweb.forms import RepositoryValidator, get_name_from_url from plinth.modules.gitweb.manifest import GIT_REPO_PATH logger = logging.getLogger(__name__) -class ValidateRepoName(argparse.Action): +def validate_repo_name(name: str) -> str: """Validate a repository name and add .git extension if necessary.""" + RepositoryValidator()(name) + if not name.endswith('.git'): + name = name + '.git' - def __call__(self, parser, namespace, values, option_string=None): - RepositoryValidator()(values) - if not values.endswith('.git'): - values = values + '.git' - setattr(namespace, self.dest, values) + return name -class ValidateRepoUrl(argparse.Action): +def validate_repo_url(url: str) -> str: """Validate a repository URL.""" - - def __call__(self, parser, namespace, values, option_string=None): - RepositoryValidator(input_should_be='url')(values) - setattr(namespace, self.dest, values) + RepositoryValidator(input_should_be='url')(url) + return url -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser( - 'setup', help='Perform post-installation operations for Gitweb') - - subparser = subparsers.add_parser('create-repo', - help='Create a new repository') - group = subparser.add_mutually_exclusive_group(required=True) - group.add_argument('--name', action=ValidateRepoName, - help='Name of the repository') - group.add_argument('--url', action=ValidateRepoUrl, - help='URL of the remote repository') - subparser.add_argument('--description', required=True, - help='Description of the repository') - subparser.add_argument('--owner', required=True, - help='Repository’s owner name') - subparser.add_argument( - '--is-private', required=False, default=False, action='store_true', - help='Allow only authorized users to access this repository') - subparser.add_argument( - '--keep-ownership', required=False, default=False, action="store_true", - help='Do not chanege ownership of the repository directory') - subparser.add_argument('--prepare-only', required=False, default=False, - action='store_true', - help='Run preparation tasks for cloning.') - subparser.add_argument('--skip-prepare', required=False, default=False, - action='store_true', - help='Skip preparation tasks for cloning.') - - subparser = subparsers.add_parser( - 'repo-info', help='Get information about the repository') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository') - - subparser = subparsers.add_parser( - 'check-repo-exists', help='Check whether the remote repository exists') - subparser.add_argument('--url', required=True, action=ValidateRepoUrl, - help='URL of the remote repository') - - subparser = subparsers.add_parser('rename-repo', - help='Rename an repository') - subparser.add_argument('--oldname', required=True, action=ValidateRepoName, - help='Old name of the repository') - subparser.add_argument('--newname', required=True, action=ValidateRepoName, - help='New name of the repository') - - subparser = subparsers.add_parser( - 'set-default-branch', help='Set default branch of the repository') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository') - subparser.add_argument('--branch', required=True, - help='Name of the branch') - - subparser = subparsers.add_parser( - 'get-branches', help='Get all the branches of the repository') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository') - - subparser = subparsers.add_parser('set-repo-description', - help='Set description of the repository') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository') - subparser.add_argument('--description', required=True, - help='Description of the repository') - - subparser = subparsers.add_parser('set-repo-owner', - help='Set repository\'s owner name') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository') - subparser.add_argument('--owner', required=True, - help='Repository’s owner name') - - subparser = subparsers.add_parser( - 'set-repo-access', help='Set repository as private or public') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository') - subparser.add_argument('--access', required=True, - choices=['public', 'private'], help='Access status') - - subparser = subparsers.add_parser('delete-repo', - help='Delete an existing repository') - subparser.add_argument('--name', required=True, action=ValidateRepoName, - help='Name of the repository to remove') - - subparsers.required = True - args = parser.parse_args() - if args.subcommand == 'create-repo' and args.name: - if args.prepare_only: - parser.error('--prepare-only can be set when using --url') - - if args.skip_prepare: - parser.error('--skip-prepare can be set when using --url') - - return args - - -def subcommand_setup(_): +@privileged +def setup(): """Disable default Apache2 Gitweb configuration.""" action_utils.webserver_disable('gitweb') if not _get_global_default_branch(): @@ -215,9 +110,9 @@ def _clone_with_progress_report(url, repo_dir): raise RuntimeError('Git repository cloning failed.', errors) -def _prepare_clone_repo(arguments): +def _prepare_clone_repo(url: str, is_private: bool): """Prepare cloning a repository.""" - repo_name = get_name_from_url(arguments.url) + repo_name = get_name_from_url(url) if not repo_name.endswith('.git'): repo_name = repo_name + '.git' @@ -226,7 +121,7 @@ def _prepare_clone_repo(arguments): status_file = os.path.join(repo_dir, 'clone_progress') try: - if arguments.is_private: + if is_private: _set_access_status(repo_name, 'private') with open(status_file, 'w', encoding='utf-8') as file_handle: file_handle.write('0') @@ -255,9 +150,8 @@ def _clone_status_line_to_percent(line): return None -def _clone_repo(arguments): +def _clone_repo(url: str, description: str, owner: str, keep_ownership: bool): """Clone a repository.""" - url = arguments.url repo = get_name_from_url(url) if not repo.endswith('.git'): repo = repo + '.git' @@ -271,26 +165,26 @@ def _clone_repo(arguments): shutil.move(os.path.join(repo_temp_path, item), repo_path) shutil.rmtree(repo_temp_path) - if not arguments.keep_ownership: + if not keep_ownership: subprocess.check_call(['chown', '-R', 'www-data:www-data', repo], cwd=GIT_REPO_PATH) - _set_repo_description(repo, arguments.description) - _set_repo_owner(repo, arguments.owner) + _set_repo_description(repo, description) + _set_repo_owner(repo, owner) -def _create_repo(arguments): +def _create_repo(repo: str, description: str, owner: str, is_private: bool, + keep_ownership: bool): """Create an empty repository.""" - repo = arguments.name try: subprocess.check_call(['git', 'init', '-q', '--bare', repo], cwd=GIT_REPO_PATH) - if not arguments.keep_ownership: + if not keep_ownership: subprocess.check_call(['chown', '-R', 'www-data:www-data', repo], cwd=GIT_REPO_PATH) - _set_repo_description(repo, arguments.description) - _set_repo_owner(repo, arguments.owner) - if arguments.is_private: + _set_repo_description(repo, description) + _set_repo_owner(repo, owner) + if is_private: _set_access_status(repo, 'private') except (subprocess.CalledProcessError, OSError): repo_path = os.path.join(GIT_REPO_PATH, repo) @@ -363,7 +257,7 @@ def _get_access_status(repo): def _set_access_status(repo, status): - """Set repository as private or public""" + """Set repository as private or public.""" private_file = os.path.join(GIT_REPO_PATH, repo, 'private') if status == 'private': open(private_file, 'a', encoding='utf-8') @@ -381,30 +275,30 @@ def _get_branches(repo): return output.decode().strip().split() -def subcommand_get_branches(arguments): +@privileged +def get_branches(name: str) -> dict[str, Any]: """Check whether a branch exists in the repository.""" - repo = arguments.name - - print( - json.dumps( - dict(default_branch=_get_default_branch(repo), - branches=_get_branches(repo)))) + repo = validate_repo_name(name) + return dict(default_branch=_get_default_branch(repo), + branches=_get_branches(repo)) -def subcommand_rename_repo(arguments): +@privileged +def rename_repo(old_name: str, new_name: str): """Rename a repository.""" - oldpath = os.path.join(GIT_REPO_PATH, arguments.oldname) - newpath = os.path.join(GIT_REPO_PATH, arguments.newname) + old_name = validate_repo_name(old_name) + new_name = validate_repo_name(new_name) + oldpath = os.path.join(GIT_REPO_PATH, old_name) + newpath = os.path.join(GIT_REPO_PATH, new_name) os.rename(oldpath, newpath) -def subcommand_set_default_branch(arguments): +@privileged +def set_default_branch(name: str, branch: str): """Set description of the repository.""" - repo = arguments.name - branch = arguments.branch - + repo = validate_repo_name(name) if branch not in _get_branches(repo): - sys.exit('No such branch.') + raise ValueError('No such branch') subprocess.check_call([ 'git', '-C', repo, 'symbolic-ref', 'HEAD', @@ -412,71 +306,81 @@ def subcommand_set_default_branch(arguments): ], cwd=GIT_REPO_PATH) -def subcommand_set_repo_description(arguments): +@privileged +def set_repo_description(name: str, description: str): """Set description of the repository.""" - _set_repo_description(arguments.name, arguments.description) + repo = validate_repo_name(name) + _set_repo_description(repo, description) -def subcommand_set_repo_owner(arguments): +@privileged +def set_repo_owner(name: str, owner: str): """Set repository's owner name.""" - _set_repo_owner(arguments.name, arguments.owner) + repo = validate_repo_name(name) + _set_repo_owner(repo, owner) -def subcommand_set_repo_access(arguments): +@privileged +def set_repo_access(name: str, access: str): """Set repository's access status.""" - _set_access_status(arguments.name, arguments.access) + repo = validate_repo_name(name) + if access not in ('public', 'private'): + raise ValueError('Invalid access parameter') + + _set_access_status(repo, access) -def subcommand_repo_info(arguments): +@privileged +def repo_info(name: str) -> dict[str, str]: """Get information about repository.""" - repo_path = os.path.join(GIT_REPO_PATH, arguments.name) + repo = validate_repo_name(name) + repo_path = os.path.join(GIT_REPO_PATH, repo) if not os.path.exists(repo_path): raise RuntimeError('Repository not found') - print( - json.dumps( - dict( - name=arguments.name[:-4], - description=_get_repo_description(arguments.name), - owner=_get_repo_owner(arguments.name), - access=_get_access_status(arguments.name), - default_branch=_get_default_branch(arguments.name), - ))) + return dict(name=repo[:-4], description=_get_repo_description(repo), + owner=_get_repo_owner(repo), access=_get_access_status(repo), + default_branch=_get_default_branch(repo)) -def subcommand_create_repo(arguments): +@privileged +def create_repo(url: Optional[str] = None, name: Optional[str] = None, + description: str = '', owner: str = '', + keep_ownership: bool = False, is_private: bool = False, + skip_prepare: bool = False, prepare_only: bool = False): """Create a new or clone a remote repository.""" - if arguments.url: - if not arguments.skip_prepare: - _prepare_clone_repo(arguments) + if url: + url = validate_repo_url(url) - if not arguments.prepare_only: - _clone_repo(arguments) - else: - _create_repo(arguments) + if name: + repo = validate_repo_name(name) + + if url: + if not skip_prepare: + _prepare_clone_repo(url, is_private) + + if not prepare_only: + _clone_repo(url, description, owner, keep_ownership) + elif repo is not None: + _create_repo(repo, description, owner, is_private, keep_ownership) -def subcommand_check_repo_exists(arguments): - """Check whether remote repository exists.""" +@privileged +def repo_exists(url: str) -> bool: + """Return whether remote repository exists.""" + url = validate_repo_url(url) env = dict(os.environ, GIT_TERMINAL_PROMPT='0') - subprocess.check_call(['git', 'ls-remote', arguments.url, 'HEAD'], - timeout=10, env=env) + try: + subprocess.check_call(['git', 'ls-remote', url, 'HEAD'], timeout=10, + env=env) + return True + except subprocess.CalledProcessError: + return False -def subcommand_delete_repo(arguments): +@privileged +def delete_repo(name: str): """Delete a git repository.""" - repo_path = os.path.join(GIT_REPO_PATH, arguments.name) + repo = validate_repo_name(name) + repo_path = os.path.join(GIT_REPO_PATH, repo) shutil.rmtree(repo_path) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/gitweb/tests/test_actions.py b/plinth/modules/gitweb/tests/test_actions.py deleted file mode 100644 index c76008289..000000000 --- a/plinth/modules/gitweb/tests/test_actions.py +++ /dev/null @@ -1,129 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Test module for gitweb module operations. -""" - -import json - -import pytest -from django.forms import ValidationError - -REPO_NAME = 'Test-repo' -REPO_DATA = { - 'name': REPO_NAME, - 'description': '', - 'owner': '', - 'access': 'private', -} - -actions_name = 'gitweb' - - -@pytest.fixture(autouse=True) -def fixture_set_repo_path(actions_module, tmpdir): - """Set a repository path in the actions module.""" - actions_module.GIT_REPO_PATH = str(tmpdir) - - -@pytest.fixture(name='existing_repo') -def fixture_existing_repo(call_action): - """A fixture to create a repository.""" - try: - call_action(['delete-repo', '--name', REPO_NAME]) - except FileNotFoundError: - pass - - call_action([ - 'create-repo', '--name', REPO_NAME, '--description', '', '--owner', '', - '--is-private', '--keep-ownership' - ]) - - -def test_create_repo(call_action): - """Test creating a repository.""" - call_action([ - 'create-repo', '--name', REPO_NAME, '--description', '', '--owner', '', - '--is-private', '--keep-ownership' - ]) - repo = json.loads(call_action(['repo-info', '--name', REPO_NAME])) - default_branch = repo.pop('default_branch') - - assert repo == REPO_DATA - assert len(default_branch) > 0 - - -def test_change_repo_medatada(call_action, existing_repo): - """Test change a metadata of the repository.""" - new_data = { - 'name': REPO_NAME, - 'description': 'description2', - 'owner': 'owner2', - 'access': 'public', - } - - call_action([ - 'set-repo-description', '--name', REPO_NAME, '--description', - new_data['description'] - ]) - call_action( - ['set-repo-owner', '--name', REPO_NAME, '--owner', new_data['owner']]) - call_action([ - 'set-repo-access', '--name', REPO_NAME, '--access', new_data['access'] - ]) - repo = json.loads(call_action(['repo-info', '--name', REPO_NAME])) - del repo['default_branch'] - - assert repo == new_data - - -def test_rename_repository(call_action, existing_repo): - """Test renaming a repository.""" - new_name = 'Test-repo_2' - - call_action(['rename-repo', '--oldname', REPO_NAME, '--newname', new_name]) - with pytest.raises(RuntimeError, match='Repository not found'): - call_action(['repo-info', '--name', REPO_NAME]) - repo = json.loads(call_action(['repo-info', '--name', new_name])) - - assert repo['name'] == new_name - - -def test_get_branches(call_action, existing_repo): - """Test getting all the branches of the repository.""" - result = json.loads(call_action(['get-branches', '--name', REPO_NAME])) - - assert 'default_branch' in result - assert result['branches'] == [] - - -def test_delete_repository(call_action, existing_repo): - """Test deleting a repository.""" - call_action(['delete-repo', '--name', REPO_NAME]) - - with pytest.raises(RuntimeError, match='Repository not found'): - call_action(['repo-info', '--name', REPO_NAME]) - - -@pytest.mark.parametrize( - 'name', - ['.Test-repo', 'Test-repo.git.git', '/root/Test-repo', 'Test-repö']) -def test_action_create_repo_with_invalid_names(call_action, name): - """Test that creating repository with invalid names fails.""" - with pytest.raises(ValidationError): - call_action([ - 'create-repo', '--name', name, '--description', '', '--owner', '', - '--keep-ownership' - ]) - - -@pytest.mark.parametrize('url', [ - 'Test-repo', 'file://root/Test-repo', 'localhost/Test-repo', - 'ssh://localhost/Test-repo', 'https://localhost/.Test-repo' -]) -def test_action_create_repo_with_invalid_urls(call_action, url): - """Test that cloning repository with invalid URL fails.""" - with pytest.raises(ValidationError): - call_action([ - 'create-repo', '--url', url, '--description', '', '--owner', '', - '--keep-ownership' - ]) diff --git a/plinth/modules/gitweb/tests/test_functional.py b/plinth/modules/gitweb/tests/test_functional.py index 26f85b552..4eb2ed558 100644 --- a/plinth/modules/gitweb/tests/test_functional.py +++ b/plinth/modules/gitweb/tests/test_functional.py @@ -237,7 +237,7 @@ def _gitweb_git_command_is_successful(command, cwd): if process.returncode != 0: if 'Authentication failed' in process.stderr.decode(): return False - print(process.stdout.decode()) + process.check_returncode() # Raise exception return True diff --git a/plinth/modules/gitweb/tests/test_privileged.py b/plinth/modules/gitweb/tests/test_privileged.py new file mode 100644 index 000000000..d837ad51a --- /dev/null +++ b/plinth/modules/gitweb/tests/test_privileged.py @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Test module for gitweb module operations.""" + +import pytest +from django.forms import ValidationError + +from plinth.modules.gitweb import privileged + +REPO_NAME = 'Test-repo' +REPO_DATA = { + 'name': REPO_NAME, + 'description': '', + 'owner': '', + 'access': 'private', +} + +pytestmark = pytest.mark.usefixtures('mock_privileged') +privileged_modules_to_mock = ['plinth.modules.gitweb.privileged'] + + +@pytest.fixture(autouse=True) +def fixture_set_repo_path(tmpdir): + """Set a repository path in the actions module.""" + privileged.GIT_REPO_PATH = str(tmpdir) + + +@pytest.fixture(name='existing_repo') +def fixture_existing_repo(): + """A fixture to create a repository.""" + try: + privileged.delete_repo(REPO_NAME) + except FileNotFoundError: + pass + + privileged.create_repo(name=REPO_NAME, description='', owner='', + keep_ownership=True, is_private=True) + + +def test_create_repo(): + """Test creating a repository.""" + privileged.create_repo(name=REPO_NAME, description='', owner='', + is_private=True, keep_ownership=True) + repo = privileged.repo_info(REPO_NAME) + default_branch = repo.pop('default_branch') + + assert repo == REPO_DATA + assert default_branch + + +def test_change_repo_medatada(existing_repo): + """Test change a metadata of the repository.""" + new_data = { + 'name': REPO_NAME, + 'description': 'description2', + 'owner': 'owner2', + 'access': 'public', + } + + privileged.set_repo_description(REPO_NAME, new_data['description']) + privileged.set_repo_owner(REPO_NAME, new_data['owner']) + privileged.set_repo_access(REPO_NAME, new_data['access']) + repo = privileged.repo_info(REPO_NAME) + del repo['default_branch'] + + assert repo == new_data + + +def test_rename_repository(existing_repo): + """Test renaming a repository.""" + new_name = 'Test-repo_2' + + privileged.rename_repo(REPO_NAME, new_name) + with pytest.raises(RuntimeError, match='Repository not found'): + privileged.repo_info(REPO_NAME) + + repo = privileged.repo_info(new_name) + assert repo['name'] == new_name + + +def test_get_branches(existing_repo): + """Test getting all the branches of the repository.""" + result = privileged.get_branches(REPO_NAME) + + assert 'default_branch' in result + assert result['branches'] == [] + + +def test_delete_repository(existing_repo): + """Test deleting a repository.""" + privileged.delete_repo(REPO_NAME) + + with pytest.raises(RuntimeError, match='Repository not found'): + privileged.repo_info(REPO_NAME) + + +@pytest.mark.parametrize( + 'name', + ['.Test-repo', 'Test-repo.git.git', '/root/Test-repo', 'Test-repö']) +def test_action_create_repo_with_invalid_names(name): + """Test that creating repository with invalid names fails.""" + with pytest.raises(ValidationError): + privileged.create_repo(name=name, description='', owner='', + keep_ownership=True) + + +@pytest.mark.parametrize('url', [ + 'Test-repo', 'file://root/Test-repo', 'localhost/Test-repo', + 'ssh://localhost/Test-repo', 'https://localhost/.Test-repo' +]) +def test_action_create_repo_with_invalid_urls(url): + """Test that cloning repository with invalid URL fails.""" + with pytest.raises(ValidationError): + privileged.create_repo(url=url, description='', owner='', + keep_ownership=True) diff --git a/plinth/modules/gitweb/tests/test_views.py b/plinth/modules/gitweb/tests/test_views.py index ce69dc507..1bf20ffec 100644 --- a/plinth/modules/gitweb/tests/test_views.py +++ b/plinth/modules/gitweb/tests/test_views.py @@ -3,7 +3,6 @@ Tests for gitweb views. """ -import json from unittest.mock import Mock, patch import pytest @@ -12,7 +11,6 @@ from django.contrib.messages.storage.fallback import FallbackStorage from django.http.response import Http404 from plinth import module_loader -from plinth.errors import ActionError from plinth.modules.gitweb import views # For all tests, use plinth.urls instead of urls configured for testing @@ -48,31 +46,28 @@ def fixture_gitweb_urls(): yield -def action_run(*args, **kwargs): - """Action return values.""" - subcommand = args[1][0] - if subcommand == 'repo-info': - return json.dumps(EXISTING_REPOS[0]) - - elif subcommand == 'check-repo-exists': - return True - - elif subcommand == 'get-branches': - return json.dumps({ - "default_branch": "main", - "branches": ["main", "branch1"] - }) - - return None - - @pytest.fixture(autouse=True) def gitweb_patch(): """Patch gitweb.""" + privileged = 'plinth.modules.gitweb.privileged' with patch('plinth.modules.gitweb.get_repo_list') as get_repo_list, \ - patch('plinth.app.App.get') as app_get, \ - patch('plinth.actions.superuser_run', side_effect=action_run), \ - patch('plinth.actions.run', side_effect=action_run): + patch('plinth.app.App.get') as app_get, \ + patch(f'{privileged}.create_repo'), \ + patch(f'{privileged}.repo_exists') as repo_exists,\ + patch(f'{privileged}.repo_info') as repo_info, \ + patch(f'{privileged}.rename_repo'), \ + patch(f'{privileged}.set_repo_description'), \ + patch(f'{privileged}.set_repo_owner'), \ + patch(f'{privileged}.set_repo_access'), \ + patch(f'{privileged}.set_default_branch'), \ + patch(f'{privileged}.delete_repo'), \ + patch(f'{privileged}.get_branches') as get_branches: + repo_exists.return_value = True + repo_info.return_value = dict(EXISTING_REPOS[0]) + get_branches.return_value = { + 'default_branch': 'main', + 'branches': ['main', 'branch1'] + } get_repo_list.return_value = [{ 'name': EXISTING_REPOS[0]['name'] }, { @@ -163,7 +158,7 @@ def test_create_repo_failed_view(rf): general_error_message = "An error occurred while creating the repository." error_description = 'some error' with patch('plinth.modules.gitweb.create_repo', - side_effect=ActionError('gitweb', '', error_description)): + side_effect=PermissionError(error_description)): form_data = { 'gitweb-name': 'something_other', 'gitweb-description': '', @@ -198,7 +193,8 @@ def test_clone_repo_view(rf): def test_clone_repo_missing_remote_view(rf): """Test that cloning non-existing repo shows correct error message.""" - with patch('plinth.modules.gitweb.repo_exists', return_value=False): + with patch('plinth.modules.gitweb.privileged.repo_exists', + return_value=False): form_data = { 'gitweb-name': 'https://example.com/test.git', 'gitweb-description': '', @@ -306,7 +302,7 @@ def test_edit_repository_no_change_view(rf): def test_edit_repository_failed_view(rf): """Test that failed repo editing sends correct error message.""" with patch('plinth.modules.gitweb.edit_repo', - side_effect=ActionError('Error')): + side_effect=PermissionError('Error')): form_data = { 'gitweb-name': 'something_other', 'gitweb-description': 'test-description', @@ -347,8 +343,8 @@ def test_delete_repository_view(rf): def test_delete_repository_fail_view(rf): """Test that failed repository deletion sends correct error message.""" - with patch('plinth.modules.gitweb.delete_repo', - side_effect=ActionError('Error')): + with patch('plinth.modules.gitweb.privileged.delete_repo', + side_effect=FileNotFoundError('Error')): response, messages = make_request(rf.post(''), views.delete, name=EXISTING_REPOS[0]['name']) diff --git a/plinth/modules/gitweb/views.py b/plinth/modules/gitweb/views.py index b6dbb088f..01f13f74f 100644 --- a/plinth/modules/gitweb/views.py +++ b/plinth/modules/gitweb/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Django views for Gitweb. -""" +"""Django views for Gitweb.""" from django.contrib import messages from django.contrib.messages.views import SuccessMessageMixin @@ -12,12 +10,11 @@ from django.urls import reverse_lazy from django.utils.translation import gettext as _ from django.views.generic import FormView -from plinth import actions from plinth import app as app_module from plinth import views -from plinth.errors import ActionError from plinth.modules import gitweb +from . import privileged from .forms import CreateRepoForm, EditRepoForm @@ -65,13 +62,12 @@ class CreateRepoView(SuccessMessageMixin, FormView): try: gitweb.create_repo(form_data['name'], form_data['description'], form_data['owner'], form_data['is_private']) - except ActionError as error: + except Exception as error: self.success_message = '' - error_text = error.args[2].split('\n')[0] messages.error( self.request, "{0} {1}".format( _('An error occurred while creating the repository.'), - error_text)) + error)) else: app_module.App.get('gitweb').update_service_access() @@ -116,7 +112,7 @@ class EditRepoView(SuccessMessageMixin, FormView): try: gitweb.edit_repo(form.initial, form_data) - except ActionError: + except Exception: messages.error(self.request, _('An error occurred during configuration.')) app_module.App.get('gitweb').update_service_access() @@ -139,9 +135,9 @@ def delete(request, name): app = app_module.App.get('gitweb') if request.method == 'POST': try: - gitweb.delete_repo(name) + privileged.delete_repo(name) messages.success(request, _('{name} deleted.').format(name=name)) - except actions.ActionError as error: + except Exception as error: messages.error( request, _('Could not delete {name}: {error}').format( diff --git a/plinth/modules/help/privileged.py b/plinth/modules/help/privileged.py new file mode 100644 index 000000000..a1e6447e8 --- /dev/null +++ b/plinth/modules/help/privileged.py @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Actions for help module.""" + +import subprocess + +from plinth.actions import privileged + + +@privileged +def get_logs() -> str: + """Get latest FreedomBox logs.""" + command = ['journalctl', '--no-pager', '--lines=100', '--unit=plinth'] + process = subprocess.run(command, check=True, stdout=subprocess.PIPE) + return process.stdout.decode() diff --git a/plinth/modules/help/views.py b/plinth/modules/help/views.py index f18d0dd1b..a020252b7 100644 --- a/plinth/modules/help/views.py +++ b/plinth/modules/help/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Help app for FreedomBox. -""" +"""Help app for FreedomBox.""" import gzip import json @@ -18,9 +16,11 @@ from django.urls import reverse from django.utils.translation import get_language_from_request from django.utils.translation import gettext as _ -from plinth import __version__, actions, cfg +from plinth import __version__, cfg from plinth.modules.upgrades import views as upgrades_views +from . import privileged + def index(request): """Serve the index page""" @@ -162,7 +162,7 @@ def download_manual(request): def status_log(request): - """Serve the last 100 lines of plinth's status log""" - output = actions.superuser_run('help', ['get-logs']) - context = {'num_lines': 100, 'data': output} + """Serve the last 100 lines of plinth's status log.""" + logs = privileged.get_logs() + context = {'num_lines': 100, 'data': logs} return TemplateResponse(request, 'statuslog.html', context) diff --git a/plinth/modules/i2p/__init__.py b/plinth/modules/i2p/__init__.py index aad01f1e1..b0e1458a2 100644 --- a/plinth/modules/i2p/__init__.py +++ b/plinth/modules/i2p/__init__.py @@ -1,11 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure I2P. -""" +"""FreedomBox app to configure I2P.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import Daemon @@ -16,7 +13,7 @@ from plinth.modules.i2p.resources import FAVORITES from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('The Invisible Internet Project is an anonymous network layer intended ' @@ -103,25 +100,11 @@ class I2PApp(app_module.App): self.disable() # Add favorites to the configuration for fav in FAVORITES: - args = [ - 'add-favorite', - '--name', - fav.get('name'), - '--url', - fav.get('url'), - ] - if 'icon' in fav: - args.extend(['--icon', fav.get('icon')]) - - if 'description' in fav: - args.extend(['--description', fav.get('description')]) - - actions.superuser_run('i2p', args) + privileged.add_favorite(fav['name'], fav['url'], + fav.get('description'), fav.get('icon')) # Tunnels to all interfaces for tunnel in tunnels_to_manage: - actions.superuser_run('i2p', [ - 'set-tunnel-property', '--name', tunnel, '--property', - 'interface', '--value', '0.0.0.0' - ]) + privileged.set_tunnel_property(tunnel, 'interface', '0.0.0.0') + self.enable() diff --git a/plinth/modules/i2p/privileged.py b/plinth/modules/i2p/privileged.py new file mode 100644 index 000000000..bd3c50395 --- /dev/null +++ b/plinth/modules/i2p/privileged.py @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure I2P.""" + +from typing import Optional + +from plinth.actions import privileged +from plinth.modules.i2p.helpers import RouterEditor, TunnelEditor + + +@privileged +def set_tunnel_property(name: str, property_: str, value: str): + """Modify the configuration file for a certain tunnel.""" + editor = TunnelEditor() + editor \ + .read_conf() \ + .set_tunnel_idx(name) \ + .set_tunnel_prop(property_, value) \ + .write_conf() + + +@privileged +def add_favorite(name: str, url: str, description: Optional[str], + icon: Optional[str]): + """Add a favorite to router.config.""" + editor = RouterEditor() + editor.read_conf().add_favorite(name, url, description, icon).write_conf() diff --git a/plinth/modules/ikiwiki/__init__.py b/plinth/modules/ikiwiki/__init__.py index f237a6657..72ab46354 100644 --- a/plinth/modules/ikiwiki/__init__.py +++ b/plinth/modules/ikiwiki/__init__.py @@ -1,12 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure ikiwiki. -""" +"""FreedomBox app to configure ikiwiki.""" from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.modules.apache.components import Webserver @@ -16,7 +13,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('ikiwiki is a simple wiki and blog application. It supports ' @@ -100,9 +97,8 @@ class IkiwikiApp(app_module.App): component.remove() # Remove from global list. def refresh_sites(self): - """Refresh blog and wiki list""" - sites = actions.run('ikiwiki', ['get-sites']).split('\n') - sites = [name.split(' ', 1) for name in sites if name != ''] + """Refresh blog and wiki list.""" + sites = privileged.get_sites() for site in sites: if not 'shortcut-ikiwiki-' + site[0] in self.components: @@ -113,5 +109,5 @@ class IkiwikiApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('ikiwiki', ['setup']) + privileged.setup() self.enable() diff --git a/plinth/modules/ikiwiki/privileged.py b/plinth/modules/ikiwiki/privileged.py new file mode 100644 index 000000000..2b61e9e5c --- /dev/null +++ b/plinth/modules/ikiwiki/privileged.py @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure ikiwiki.""" + +import os +import re +import shutil +import subprocess +from typing import Tuple + +from plinth.actions import privileged + +SETUP_WIKI = '/etc/ikiwiki/plinth-wiki.setup' +SETUP_BLOG = '/etc/ikiwiki/plinth-blog.setup' +SITE_PATH = '/var/www/ikiwiki' +WIKI_PATH = '/var/lib/ikiwiki' + + +def _is_safe_path(basedir, path): + """Return whether a path is safe.""" + return os.path.realpath(path).startswith(basedir) + + +@privileged +def setup(): + """Write Apache configuration and wiki/blog setup scripts.""" + if not os.path.exists(SITE_PATH): + os.makedirs(SITE_PATH) + + +def _get_title(site): + """Get blog or wiki title.""" + try: + with open(os.path.join(SITE_PATH, site, 'index.html'), + encoding='utf-8') as index_file: + match = re.search(r'(.*)', index_file.read()) + if match: + return match[1] + except FileNotFoundError: + pass + + return site + + +@privileged +def get_sites() -> list[Tuple[str, str]]: + """Get wikis and blogs.""" + sites = [] + if os.path.exists(SITE_PATH): + for site in os.listdir(SITE_PATH): + if not os.path.isdir(os.path.join(SITE_PATH, site)): + continue + + title = _get_title(site) + sites.append((site, title)) + + return sites + + +@privileged +def create_wiki(wiki_name: str, admin_name: str, admin_password: str): + """Create a wiki.""" + pw_bytes = admin_password.encode() + input_ = pw_bytes + b'\n' + pw_bytes + subprocess.run(['ikiwiki', '-setup', SETUP_WIKI, wiki_name, admin_name], + stdout=subprocess.PIPE, input=input_, + stderr=subprocess.PIPE, + env=dict(os.environ, PERL_UNICODE='AS'), check=True) + + +@privileged +def create_blog(blog_name: str, admin_name: str, admin_password: str): + """Create a blog.""" + pw_bytes = admin_password.encode() + input_ = pw_bytes + b'\n' + pw_bytes + subprocess.run(['ikiwiki', '-setup', SETUP_BLOG, blog_name, admin_name], + stdout=subprocess.PIPE, input=input_, + stderr=subprocess.PIPE, env=dict(os.environ, + PERL_UNICODE='AS')) + + +@privileged +def delete(name: str): + """Delete a wiki or blog.""" + html_folder = os.path.join(SITE_PATH, name) + wiki_folder = os.path.join(WIKI_PATH, name) + + if not (_is_safe_path(SITE_PATH, html_folder) + and _is_safe_path(WIKI_PATH, wiki_folder)): + raise ValueError( + 'Error: {0} is not a correct wiki/blog name.'.format(name)) + + try: + shutil.rmtree(html_folder) + shutil.rmtree(wiki_folder) + shutil.rmtree(wiki_folder + '.git') + os.remove(wiki_folder + '.setup') + except FileNotFoundError: + raise RuntimeError('Unable to delete wiki/blog') diff --git a/plinth/modules/ikiwiki/views.py b/plinth/modules/ikiwiki/views.py index b7f7c4e20..4635cae8a 100644 --- a/plinth/modules/ikiwiki/views.py +++ b/plinth/modules/ikiwiki/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring ikiwiki. -""" +"""FreedomBox app for configuring ikiwiki.""" from django.contrib import messages from django.shortcuts import redirect @@ -9,10 +7,10 @@ from django.template.response import TemplateResponse from django.urls import reverse_lazy from django.utils.translation import gettext as _ -from plinth import actions from plinth import app as app_module from plinth import views +from . import privileged from .forms import IkiwikiCreateForm @@ -67,12 +65,9 @@ def create(request): def _create_wiki(request, name, admin_name, admin_password): """Create wiki.""" try: - actions.superuser_run( - 'ikiwiki', - ['create-wiki', '--wiki_name', name, '--admin_name', admin_name], - input=admin_password.encode()) + privileged.create_wiki(name, admin_name, admin_password) messages.success(request, _('Created wiki {name}.').format(name=name)) - except actions.ActionError as error: + except Exception as error: messages.error(request, _('Could not create wiki: {error}').format(error=error)) @@ -80,12 +75,9 @@ def _create_wiki(request, name, admin_name, admin_password): def _create_blog(request, name, admin_name, admin_password): """Create blog.""" try: - actions.superuser_run( - 'ikiwiki', - ['create-blog', '--blog_name', name, '--admin_name', admin_name], - input=admin_password.encode()) + privileged.create_blog(name, admin_name, admin_password) messages.success(request, _('Created blog {name}.').format(name=name)) - except actions.ActionError as error: + except Exception as error: messages.error(request, _('Could not create blog: {error}').format(error=error)) @@ -100,11 +92,11 @@ def delete(request, name): title = app.components['shortcut-ikiwiki-' + name].name if request.method == 'POST': try: - actions.superuser_run('ikiwiki', ['delete', '--name', name]) + privileged.delete(name) app.remove_shortcut(name) messages.success(request, _('{title} deleted.').format(title=title)) - except actions.ActionError as error: + except Exception as error: messages.error( request, _('Could not delete {title}: {error}').format( diff --git a/plinth/modules/infinoted/__init__.py b/plinth/modules/infinoted/__init__.py index 315b18161..e70d684f6 100644 --- a/plinth/modules/infinoted/__init__.py +++ b/plinth/modules/infinoted/__init__.py @@ -6,7 +6,6 @@ FreedomBox app for infinoted. from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -15,7 +14,7 @@ from plinth.modules.firewall.components import Firewall from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('infinoted is a server for Gobby, a collaborative text editor.'), @@ -77,5 +76,5 @@ class InfinotedApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('infinoted', ['setup']) + privileged.setup() self.enable() diff --git a/actions/infinoted b/plinth/modules/infinoted/privileged.py old mode 100755 new mode 100644 similarity index 85% rename from actions/infinoted rename to plinth/modules/infinoted/privileged.py index aef33246a..9675030a1 --- a/actions/infinoted +++ b/plinth/modules/infinoted/privileged.py @@ -1,10 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for infinoted. -""" +"""Configure infinoted.""" -import argparse import grp import os import pwd @@ -13,6 +9,7 @@ import subprocess import time from plinth import action_utils +from plinth.actions import privileged DATA_DIR = '/var/lib/infinoted' KEY_DIR = '/etc/infinoted' @@ -103,17 +100,6 @@ WantedBy=multi-user.target ''' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Configure infinoted after install') - - subparsers.required = True - return parser.parse_args() - - def _kill_daemon(): """Try to kill the infinoted daemon for upto 5 minutes.""" end_time = time.time() + 300 @@ -127,7 +113,8 @@ def _kill_daemon(): time.sleep(1) -def subcommand_setup(_): +@privileged +def setup(): """Configure infinoted after install.""" if not os.path.isfile(CONF_PATH): with open(CONF_PATH, 'w', encoding='utf-8') as file_handle: @@ -180,16 +167,3 @@ def subcommand_setup(_): group='infinoted') action_utils.service_enable('infinoted') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/letsencrypt/__init__.py b/plinth/modules/letsencrypt/__init__.py index 76b067e10..3718e67c9 100644 --- a/plinth/modules/letsencrypt/__init__.py +++ b/plinth/modules/letsencrypt/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for using Let's Encrypt. -""" +"""FreedomBox app for using Let's Encrypt.""" import json import logging @@ -9,10 +7,8 @@ import pathlib from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu -from plinth.errors import ActionError from plinth.modules import names from plinth.modules.apache.components import diagnose_url from plinth.modules.backups.components import BackupRestore @@ -21,7 +17,7 @@ from plinth.package import Packages from plinth.signals import domain_added, domain_removed, post_app_loading from plinth.utils import format_lazy -from . import components, manifest +from . import components, manifest, privileged _description = [ format_lazy( @@ -102,14 +98,12 @@ class LetsEncryptApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('letsencrypt', - ['setup', '--old-version', - str(old_version)]) + privileged.setup(old_version) def certificate_obtain(domain): """Obtain a certificate for a domain and notify handlers.""" - actions.superuser_run('letsencrypt', ['obtain', '--domain', domain]) + privileged.obtain(domain) components.on_certificate_event('obtained', [domain], None) @@ -124,7 +118,7 @@ def certificate_reobtain(domain): trigger obtain event (LE will trigger a renewal event). """ - actions.superuser_run('letsencrypt', ['obtain', '--domain', domain]) + privileged.obtain(domain) def certificate_revoke(domain, really_revoke=True): @@ -138,20 +132,20 @@ def certificate_revoke(domain, really_revoke=True): obtaining certificates on the Let's Encrypt servers). """ if really_revoke: - actions.superuser_run('letsencrypt', ['revoke', '--domain', domain]) + privileged.revoke(domain) components.on_certificate_event('revoked', [domain], None) def certificate_delete(domain): """Delete a certificate for a domain and notify handlers.""" - actions.superuser_run('letsencrypt', ['delete', '--domain', domain]) + privileged.delete(domain) components.on_certificate_event('deleted', [domain], None) def on_domain_added(sender, domain_type='', name='', description='', services=None, **kwargs): - """Obtain a certificate for the new domain""" + """Obtain a certificate for the new domain.""" if not DomainType.get(domain_type).can_have_certificate: return False @@ -167,12 +161,12 @@ def on_domain_added(sender, domain_type='', name='', description='', logger.info('Obtaining certificate for %s', name) certificate_obtain(name) return True - except ActionError: + except Exception: return False def on_domain_removed(sender, domain_type, name='', **kwargs): - """Revoke Let's Encrypt certificate for the removed domain""" + """Revoke Let's Encrypt certificate for the removed domain.""" if not DomainType.get(domain_type).can_have_certificate: return False @@ -181,7 +175,7 @@ def on_domain_removed(sender, domain_type, name='', **kwargs): logger.info('Revoking certificate for %s', name) certificate_revoke(name, really_revoke=False) return True - except ActionError as exception: + except Exception as exception: logger.warning('Failed to revoke certificate for %s: %s', name, exception.args[2]) return False @@ -189,8 +183,7 @@ def on_domain_removed(sender, domain_type, name='', **kwargs): def get_status(): """Get the current settings.""" - status = actions.superuser_run('letsencrypt', ['get-status']) - status = json.loads(status) + status = privileged.get_status() for domain in names.components.DomainName.list(): if domain.domain_type.can_have_certificate: @@ -247,9 +240,7 @@ def certificate_get_last_seen_modified_time(lineage): def certificate_set_last_seen_modified_time(lineage): """Write to store a certificate's last seen expiry date.""" lineage = pathlib.Path(lineage) - output = actions.superuser_run( - 'letsencrypt', ['get-modified-time', '--domain', lineage.name]) - modified_time = int(output) + modified_time = privileged.get_modified_time(lineage.name) from plinth import kvstore info = kvstore.get_default('letsencrypt_certificate_info', '{}') diff --git a/plinth/modules/letsencrypt/components.py b/plinth/modules/letsencrypt/components.py index e6f1a29ac..f951277fa 100644 --- a/plinth/modules/letsencrypt/components.py +++ b/plinth/modules/letsencrypt/components.py @@ -1,15 +1,15 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -App component for other apps to use handle Let's Encrypt certificates. -""" +"""App component for other apps to use handle Let's Encrypt certificates.""" -import json import logging import pathlib import threading -from plinth import actions, app +from plinth import app from plinth.modules.names.components import DomainName +from plinth.privileged import service as service_privileged + +from . import privileged logger = logging.getLogger(__name__) @@ -169,7 +169,7 @@ class LetsEncrypt(app.FollowerComponent): self._copy_self_signed_certificates([domain]) for daemon in self.daemons: - actions.superuser_run('service', ['try-restart', daemon]) + service_privileged.try_restart(daemon) def get_status(self): """Return the status of certificates for all interested domains. @@ -214,7 +214,7 @@ class LetsEncrypt(app.FollowerComponent): self._copy_letsencrypt_certificates(interested_domains, lineage) for daemon in self.daemons: - actions.superuser_run('service', ['try-restart', daemon]) + service_privileged.try_restart(daemon) def on_certificate_renewed(self, domains, lineage): """Handle event when a certificate is renewed. @@ -248,7 +248,7 @@ class LetsEncrypt(app.FollowerComponent): self._copy_self_signed_certificates(interested_domains) for daemon in self.daemons: - actions.superuser_run('service', ['try-restart', daemon]) + service_privileged.try_restart(daemon) def on_certificate_deleted(self, domains, lineage): """Handle event when a certificate is deleted. @@ -327,14 +327,11 @@ class LetsEncrypt(app.FollowerComponent): source_certificate_path, private_key_path, certificate_path): """Copy certificate for a single domain.""" - actions.superuser_run('letsencrypt', [ - 'copy-certificate', '--managing-app', self.managing_app, - '--user-owner', self.user_owner, '--group-owner', self.group_owner, - '--source-private-key-path', - str(source_private_key_path), '--source-certificate-path', - str(source_certificate_path), '--private-key-path', - private_key_path, '--certificate-path', certificate_path - ]) + privileged.copy_certificate(self.managing_app, + str(source_private_key_path), + str(source_certificate_path), + private_key_path, certificate_path, + self.user_owner, self.group_owner) def _compare_certificate(self, domain, lineage): """Compare LE certificate with app certificate.""" @@ -342,14 +339,11 @@ class LetsEncrypt(app.FollowerComponent): source_certificate_path = pathlib.Path(lineage) / 'fullchain.pem' private_key_path = self.private_key_path.format(domain=domain) certificate_path = self.certificate_path.format(domain=domain) - output = actions.superuser_run('letsencrypt', [ - 'compare-certificate', '--managing-app', self.managing_app, - '--source-private-key-path', - str(source_private_key_path), '--source-certificate-path', - str(source_certificate_path), '--private-key-path', - private_key_path, '--certificate-path', certificate_path - ]) - return json.loads(output)['result'] + return privileged.compare_certificate(self.managing_app, + str(source_private_key_path), + str(source_certificate_path), + private_key_path, + certificate_path) def on_certificate_event(event, domains, lineage): diff --git a/plinth/modules/letsencrypt/privileged.py b/plinth/modules/letsencrypt/privileged.py new file mode 100644 index 000000000..d77e9e29a --- /dev/null +++ b/plinth/modules/letsencrypt/privileged.py @@ -0,0 +1,359 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure Let's Encrypt.""" + +import filecmp +import glob +import importlib +import inspect +import os +import pathlib +import re +import shutil +import subprocess +import sys +from typing import Any + +import configobj + +from plinth import action_utils +from plinth import app as app_module +from plinth import cfg +from plinth.actions import privileged +from plinth.modules import letsencrypt as le + +TEST_MODE = False +LE_DIRECTORY = '/etc/letsencrypt/' +ETC_SSL_DIRECTORY = '/etc/ssl/' +RENEWAL_DIRECTORY = '/etc/letsencrypt/renewal/' +AUTHENTICATOR = 'webroot' +WEB_ROOT_PATH = '/var/www/html' +APACHE_PREFIX = '/etc/apache2/sites-available/' +APACHE_CONFIGURATION = ''' +Use FreedomBoxTLSSiteMacro {domain} +''' + + +def _get_certificate_expiry(domain: str) -> str: + """Return the expiry date of a certificate.""" + certificate_file = os.path.join(le.LIVE_DIRECTORY, domain, 'cert.pem') + output = subprocess.check_output( + ['openssl', 'x509', '-enddate', '-noout', '-in', certificate_file]) + return output.decode().strip().split('=')[1] + + +def _get_modified_time(domain: str) -> int: + """Return the last modified time of a certificate.""" + certificate_file = pathlib.Path(le.LIVE_DIRECTORY) / domain / 'cert.pem' + return int(certificate_file.stat().st_mtime) + + +def _get_validity_status(domain: str) -> str: + """Return validity status of a certificate; valid, revoked, expired.""" + output = subprocess.check_output(['certbot', 'certificates', '-d', domain]) + line = output.decode(sys.stdout.encoding) + + match = re.search(r'INVALID: (.*)\)', line) + if match is not None: + validity = match.group(1).lower() + elif re.search('VALID', line) is not None: + validity = 'valid' + else: + validity = 'unknown' + + return validity + + +def _get_status() -> dict[str, Any]: + """Return Python dictionary of currently configured domains. + + Should be run as root, otherwise might yield a wrong, empty answer. + """ + try: + domains = os.listdir(le.LIVE_DIRECTORY) + except OSError: + domains = [] + + domains = [ + domain for domain in domains + if os.path.isdir(os.path.join(le.LIVE_DIRECTORY, domain)) + ] + + domain_status = {} + for domain in domains: + domain_status[domain] = { + 'certificate_available': + True, + 'expiry_date': + _get_certificate_expiry(domain), + 'web_enabled': + action_utils.webserver_is_enabled(domain, kind='site'), + 'validity': + _get_validity_status(domain), + 'lineage': + str(pathlib.Path(le.LIVE_DIRECTORY) / domain), + 'modified_time': + _get_modified_time(domain) + } + return domain_status + + +@privileged +def setup(old_version: int): + """Upgrade old site configuration to new macro based style. + + Nothing to do for first time setup and for newer versions. + """ + if old_version == 2: + _remove_old_hooks() + return + + if old_version != 1: + return + + domain_status = _get_status() + with action_utils.WebserverChange() as webserver_change: + for domain in domain_status: + _setup_webserver_config(domain, webserver_change) + + +@privileged +def get_status() -> dict[str, Any]: + """Return a dictionary of currently configured domains.""" + domain_status = _get_status() + return {'domains': domain_status} + + +@privileged +def get_modified_time(domain: str) -> int: + """Return the modified time of a certificate as integer.""" + return _get_modified_time(domain) + + +@privileged +def revoke(domain: str): + """Disable a domain and revoke the certificate.""" + cert_path = pathlib.Path(le.LIVE_DIRECTORY) / domain / 'cert.pem' + if cert_path.exists(): + command = [ + 'certbot', 'revoke', '--non-interactive', '--domain', domain, + '--cert-path', + str(cert_path) + ] + if TEST_MODE: + command.append('--staging') + + process = subprocess.Popen(command, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + _, stderr = process.communicate() + if process.returncode: + raise RuntimeError('Error revoking certificate: {error}'.format( + error=stderr.decode())) + + action_utils.webserver_disable(domain, kind='site') + + +@privileged +def obtain(domain: str): + """Obtain a certificate for a domain and setup website.""" + command = [ + 'certbot', 'certonly', '--non-interactive', '--text', '--agree-tos', + '--register-unsafely-without-email', '--domain', domain, + '--authenticator', AUTHENTICATOR, '--webroot-path', WEB_ROOT_PATH, + '--renew-by-default' + ] + if TEST_MODE: + command.append('--staging') + + process = subprocess.Popen(command, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + _, stderr = process.communicate() + if process.returncode: + raise RuntimeError('Error obtaining certificate: {error}'.format( + error=stderr.decode())) + + with action_utils.WebserverChange() as webserver_change: + _setup_webserver_config(domain, webserver_change) + + +def _remove_old_hooks(): + """Remove old style renewal hooks from individual configuration files. + + This has been replaced with global hooks by adding script files in + directory /etc/letsencrypt/renewal-hooks/{pre,post,deploy}/. + """ + for file_path in glob.glob(RENEWAL_DIRECTORY + '*.conf'): + try: + _remove_old_hooks_from_file(file_path) + except Exception as exception: + print('Error removing hooks from file:', file_path, exception) + + +def _remove_old_hooks_from_file(file_path: str): + """Remove old style hooks from a single configuration file.""" + config = configobj.ConfigObj(file_path) + edited = False + for line in config.initial_comment: + if 'edited by plinth' in line.lower(): + edited = True + + if not edited: + return + + config.initial_comment = [ + line for line in config.initial_comment + if 'edited by plinth' not in line.lower() + ] + + if 'pre_hook' in config['renewalparams']: + del config['renewalparams']['pre_hook'] + + if 'renew_hook' in config['renewalparams']: + del config['renewalparams']['renew_hook'] + + if 'post_hook' in config['renewalparams']: + del config['renewalparams']['post_hook'] + + config.write() + + +@privileged +def copy_certificate(managing_app: str, source_private_key: str, + source_certificate: str, private_key: str, + certificate: str, user_owner: str, group_owner: str): + """Copy certificate from LE directory to daemon's directory. + + Set ownership and permissions as requested needed by the daemon. + + """ + source_private_key_path = pathlib.Path(source_private_key).resolve() + _assert_source_directory(source_private_key_path) + source_certificate_path = pathlib.Path(source_certificate).resolve() + _assert_source_directory(source_certificate_path) + + private_key_path = pathlib.Path(private_key).resolve() + _assert_managed_path(managing_app, private_key_path) + certificate_path = pathlib.Path(certificate).resolve() + _assert_managed_path(managing_app, certificate_path) + + # Create directories, owned by root + private_key_path.parent.mkdir(mode=0o755, parents=True, exist_ok=True) + certificate_path.parent.mkdir(mode=0o755, parents=True, exist_ok=True) + + # Private key is only accessible to the user owner + old_mask = os.umask(0o177) + shutil.copyfile(source_private_key_path, private_key_path) + + if certificate_path != private_key_path: + # Certificate is only writable by the user owner + os.umask(0o133) + shutil.copyfile(source_certificate_path, certificate_path) + else: + # If private key and certificate are the same file, append one after + # the other. + source_certificate_bytes = source_certificate_path.read_bytes() + with private_key_path.open(mode='a+b') as file_handle: + file_handle.write(source_certificate_bytes) + + os.umask(old_mask) + + shutil.chown(certificate_path, user=user_owner, group=group_owner) + shutil.chown(private_key_path, user=user_owner, group=group_owner) + + +@privileged +def compare_certificate(managing_app: str, source_private_key: str, + source_certificate: str, private_key: str, + certificate: str) -> bool: + """Compare LE certificate with an app certificate.""" + source_private_key_path = pathlib.Path(source_private_key) + source_certificate_path = pathlib.Path(source_certificate) + _assert_source_directory(source_private_key_path) + _assert_source_directory(source_certificate_path) + + private_key_path = pathlib.Path(private_key) + certificate_path = pathlib.Path(certificate) + _assert_managed_path(managing_app, private_key) + _assert_managed_path(managing_app, certificate) + + result = False + try: + if filecmp.cmp(source_certificate_path, certificate_path) and \ + filecmp.cmp(source_private_key_path, private_key_path): + result = True + except FileNotFoundError: + result = False + + return result + + +def _assert_source_directory(path): + """Assert that a path is a valid source of a certificates.""" + assert (str(path).startswith(LE_DIRECTORY) + or str(path).startswith(ETC_SSL_DIRECTORY)) + + +def _get_managed_path(path): + """Return the managed path given a certificate path.""" + if '{domain}' in path: + return pathlib.Path(path.partition('{domain}')[0]) + + return pathlib.Path(path).parent + + +def _assert_managed_path(module, path): + """Check that path is in fact managed by module.""" + cfg.read() + module_file = pathlib.Path(cfg.config_dir) / 'modules-enabled' / module + module_path = module_file.read_text().strip() + + module = importlib.import_module(module_path) + module_classes = inspect.getmembers(module, inspect.isclass) + app_classes = [ + cls[1] for cls in module_classes if issubclass(cls[1], app_module.App) + ] + + managed_paths = [] + for cls in app_classes: + app = cls() + from plinth.modules.letsencrypt.components import LetsEncrypt + components = app.get_components_of_type(LetsEncrypt) + for component in components: + if component.private_key_path: + managed_paths.append( + _get_managed_path(component.private_key_path)) + if component.certificate_path: + managed_paths.append( + _get_managed_path(component.certificate_path)) + + if not set(path.parents).intersection(set(managed_paths)): + raise AssertionError('Not a managed path') + + +@privileged +def delete(domain: str): + """Disable a domain and delete the certificate.""" + command = ['certbot', 'delete', '--non-interactive', '--cert-name', domain] + process = subprocess.Popen(command, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + _, stderr = process.communicate() + if process.returncode: + raise RuntimeError('Error deleting certificate: {error}'.format( + error=stderr.decode())) + + action_utils.webserver_disable(domain, kind='site') + + +def _setup_webserver_config(domain, webserver_change): + """Create SSL web server configuration for a domain. + + Do so only if there is no configuration existing. + """ + file_name = os.path.join(APACHE_PREFIX, domain + '.conf') + if os.path.isfile(file_name): + os.rename(file_name, file_name + '.fbx-bak') + + with open(file_name, 'w', encoding='utf-8') as file_handle: + file_handle.write(APACHE_CONFIGURATION.format(domain=domain)) + + webserver_change.enable('freedombox-tls-site-macro', kind='config') + webserver_change.enable(domain, kind='site') diff --git a/plinth/modules/letsencrypt/tests/test_components.py b/plinth/modules/letsencrypt/tests/test_components.py index 942db5f0a..320c235ad 100644 --- a/plinth/modules/letsencrypt/tests/test_components.py +++ b/plinth/modules/letsencrypt/tests/test_components.py @@ -3,7 +3,6 @@ Test the Let's Encrypt component for managing certificates. """ -import json from unittest.mock import call, patch import pytest @@ -30,6 +29,29 @@ def fixture_component(): managing_app='test-app') +@pytest.fixture(name='try_restart') +def fixture_try_restart(): + """Patch and return service.try_restart privileged call.""" + with patch('plinth.privileged.service.try_restart') as try_restart: + yield try_restart + + +@pytest.fixture(name='copy_certificate') +def fixture_copy_certificate(): + """Patch and return privileged.copy_certificate call.""" + with patch('plinth.modules.letsencrypt.privileged.copy_certificate' + ) as copy_certificate: + yield copy_certificate + + +@pytest.fixture(name='compare_certificate') +def fixture_compare_certificate(): + """Patch and return privileged.compare_certificate call.""" + with patch('plinth.modules.letsencrypt.privileged.compare_certificate' + ) as compare_certificate: + yield compare_certificate + + @pytest.fixture(name='get_status') def fixture_get_status(): """Return patched letsencrypt.get_status() method.""" @@ -65,13 +87,6 @@ def fixture_domain_list(): yield domain_list -@pytest.fixture(name='superuser_run') -def fixture_superuser_run(): - """Return patched plinth.actions.superuser_run() method.""" - with patch('plinth.actions.superuser_run') as superuser_run: - yield superuser_run - - def test_init_without_arguments(): """Test that component is initialized with defaults properly.""" component = LetsEncrypt('test-component') @@ -133,13 +148,8 @@ def test_list(): assert set(LetsEncrypt.list()) == {component1, component2} -def _assert_copy_certificate_called(component, superuser_run, domains): +def _assert_copy_certificate_called(component, copy_certificate, domains): """Check that copy certificate calls have been made properly.""" - copy_calls = [ - mock_call for mock_call in superuser_run.mock_calls - if mock_call[1][0] == 'letsencrypt' - and mock_call[1][1][0] == 'copy-certificate' - ] expected_calls = [] for domain, domain_status in domains.items(): if domain_status == 'valid': @@ -153,83 +163,72 @@ def _assert_copy_certificate_called(component, superuser_run, domains): private_key_path = '/etc/test-app/{}/private.path'.format(domain) certificate_path = '/etc/test-app/{}/certificate.path'.format(domain) - expected_call = call('letsencrypt', [ - 'copy-certificate', '--managing-app', component.managing_app, - '--user-owner', component.user_owner, '--group-owner', - component.group_owner, '--source-private-key-path', - str(source_private_key_path), '--source-certificate-path', - str(source_certificate_path), '--private-key-path', - private_key_path, '--certificate-path', certificate_path - ]) + expected_call = call(component.managing_app, + str(source_private_key_path), + str(source_certificate_path), private_key_path, + certificate_path, component.user_owner, + component.group_owner) expected_calls.append(expected_call) - assert len(expected_calls) == len(copy_calls) - for expected_call in expected_calls: - print(expected_call) - print(copy_calls) - assert expected_call in copy_calls + copy_certificate.assert_has_calls(expected_calls, any_order=True) -def _assert_restarted_daemons(daemons, superuser_run): +def _assert_restarted_daemons(daemons, try_restart): """Check that a call has restarted the daemons of a component.""" - run_calls = [ - mock_call for mock_call in superuser_run.mock_calls - if mock_call[1][0] == 'service' - ] - expected_calls = [ - call('service', ['try-restart', daemon]) for daemon in daemons - ] - assert len(expected_calls) == len(run_calls) - for expected_call in expected_calls: - assert expected_call in run_calls + expected_calls = [call(daemon) for daemon in daemons] + try_restart.assert_has_calls(expected_calls, any_order=True) -def test_setup_certificates(superuser_run, get_status, component): +def test_setup_certificates(copy_certificate, try_restart, get_status, + component): """Test that initial copying of certs for an app works.""" component.setup_certificates() - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'valid', 'invalid.example': 'invalid' }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_setup_certificates_without_copy(superuser_run, get_status, component): +def test_setup_certificates_without_copy(copy_certificate, try_restart, + get_status, component): """Test that initial copying of certs for an app works.""" component.should_copy_certificates = False component.setup_certificates() - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons(component.daemons, try_restart) -def test_setup_certificates_with_app_domains(superuser_run, get_status, - component): +def test_setup_certificates_with_app_domains(copy_certificate, try_restart, + get_status, component): """Test that initial copying of certs for an app works.""" component._domains = ['irrelevant1.example', 'irrelevant2.example'] component.setup_certificates( app_domains=['valid.example', 'invalid.example']) - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'valid', 'invalid.example': 'invalid' }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_setup_certificates_with_all_domains(domain_list, superuser_run, - get_status, component): +def test_setup_certificates_with_all_domains(domain_list, copy_certificate, + try_restart, get_status, + component): """Test that initial copying for certs works when app domains is '*'.""" component._domains = '*' component.setup_certificates() _assert_copy_certificate_called( - component, superuser_run, { + component, copy_certificate, { 'valid.example': 'valid', 'invalid1.example': 'invalid', 'invalid2.example': 'invalid' }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def _assert_compare_certificate_called(component, superuser_run, domains): +def _assert_compare_certificate_called(component, compare_certificate, + domains): """Check that compare certificate was called properly.""" expected_calls = [] for domain in domains: @@ -239,37 +238,34 @@ def _assert_compare_certificate_called(component, superuser_run, domains): '/etc/letsencrypt/live/{}/fullchain.pem'.format(domain) private_key_path = '/etc/test-app/{}/private.path'.format(domain) certificate_path = '/etc/test-app/{}/certificate.path'.format(domain) - expected_call = call('letsencrypt', [ - 'compare-certificate', '--managing-app', component.managing_app, - '--source-private-key-path', - str(source_private_key_path), '--source-certificate-path', - str(source_certificate_path), '--private-key-path', - private_key_path, '--certificate-path', certificate_path - ]) + expected_call = call(component.managing_app, + str(source_private_key_path), + str(source_certificate_path), private_key_path, + certificate_path) expected_calls.append(expected_call) - superuser_run.assert_has_calls(expected_calls) + compare_certificate.assert_has_calls(expected_calls, any_order=True) -def test_get_status(component, superuser_run, get_status): +def test_get_status(component, compare_certificate, get_status): """Test that getting domain status works.""" - superuser_run.return_value = json.dumps({'result': True}) + compare_certificate.return_value = True assert component.get_status() == { 'valid.example': 'valid', 'invalid.example': 'self-signed' } - _assert_compare_certificate_called(component, superuser_run, + _assert_compare_certificate_called(component, compare_certificate, ['valid.example']) -def test_get_status_outdate_copy(component, superuser_run, get_status): +def test_get_status_outdate_copy(component, compare_certificate, get_status): """Test that getting domain status works with outdated copy.""" - superuser_run.return_value = json.dumps({'result': False}) + compare_certificate.return_value = False assert component.get_status() == { 'valid.example': 'outdated-copy', 'invalid.example': 'self-signed' } - _assert_compare_certificate_called(component, superuser_run, + _assert_compare_certificate_called(component, compare_certificate, ['valid.example']) @@ -282,130 +278,139 @@ def test_get_status_without_copy(component, get_status): } -def test_on_certificate_obtained(superuser_run, component): +def test_on_certificate_obtained(copy_certificate, try_restart, component): """Test that certificate obtained event handler works.""" component.on_certificate_obtained(['valid.example', 'irrelevant.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'valid', }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_obtained_with_all_domains(superuser_run, component): +def test_on_certificate_obtained_with_all_domains(copy_certificate, + try_restart, component): """Test that certificate obtained event handler works for app with all domains. """ component._domains = '*' component.on_certificate_obtained(['valid.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'valid', }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_obtained_irrelevant(superuser_run, component): +def test_on_certificate_obtained_irrelevant(copy_certificate, try_restart, + component): """Test that certificate obtained event handler works with irrelevant domain. """ component.on_certificate_obtained( ['irrelevant.example'], '/etc/letsencrypt/live/irrelevant.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons([], superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons([], try_restart) -def test_on_certificate_obtained_without_copy(superuser_run, component): +def test_on_certificate_obtained_without_copy(copy_certificate, try_restart, + component): """Test that certificate obtained event handler works without copying.""" component.should_copy_certificates = False component.on_certificate_obtained(['valid.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_renewed(superuser_run, component): +def test_on_certificate_renewed(copy_certificate, try_restart, component): """Test that certificate renewed event handler works.""" component.on_certificate_renewed(['valid.example', 'irrelevant.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'valid', }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_renewed_irrelevant(superuser_run, component): +def test_on_certificate_renewed_irrelevant(copy_certificate, try_restart, + component): """Test that certificate renewed event handler works for irrelevant domains. """ component.on_certificate_renewed( ['irrelevant.example'], '/etc/letsencrypt/live/irrelevant.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons([], superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons([], try_restart) -def test_on_certificate_renewed_without_copy(superuser_run, component): +def test_on_certificate_renewed_without_copy(copy_certificate, try_restart, + component): """Test that certificate renewed event handler works without copying.""" component.should_copy_certificates = False component.on_certificate_renewed(['valid.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_revoked(superuser_run, component): +def test_on_certificate_revoked(copy_certificate, try_restart, component): """Test that certificate revoked event handler works.""" component.on_certificate_revoked(['valid.example', 'irrelevant.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'invalid', }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_revoked_irrelevant(superuser_run, component): +def test_on_certificate_revoked_irrelevant(copy_certificate, try_restart, + component): """Test that certificate revoked event handler works for irrelevant domains. """ component.on_certificate_revoked( ['irrelevant.example'], '/etc/letsencrypt/live/irrelevant.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons([], superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons([], try_restart) -def test_on_certificate_revoked_without_copy(superuser_run, component): +def test_on_certificate_revoked_without_copy(copy_certificate, try_restart, + component): """Test that certificate revoked event handler works without copying.""" component.should_copy_certificates = False component.on_certificate_revoked(['valid.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_deleted(superuser_run, component): +def test_on_certificate_deleted(copy_certificate, try_restart, component): """Test that certificate deleted event handler works.""" component.on_certificate_deleted(['valid.example', 'irrelevant.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, { + _assert_copy_certificate_called(component, copy_certificate, { 'valid.example': 'invalid', }) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_restarted_daemons(component.daemons, try_restart) -def test_on_certificate_deleted_irrelevant(superuser_run, component): +def test_on_certificate_deleted_irrelevant(copy_certificate, try_restart, + component): """Test that certificate deleted event handler works for irrelevant domains. """ component.on_certificate_deleted( ['irrelevant.example'], '/etc/letsencrypt/live/irrelevant.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons([], superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons([], try_restart) -def test_on_certificate_deleted_without_copy(superuser_run, component): +def test_on_certificate_deleted_without_copy(copy_certificate, try_restart, + component): """Test that certificate deleted event handler works without copying.""" component.should_copy_certificates = False component.on_certificate_deleted(['valid.example'], '/etc/letsencrypt/live/valid.example/') - _assert_copy_certificate_called(component, superuser_run, {}) - _assert_restarted_daemons(component.daemons, superuser_run) + _assert_copy_certificate_called(component, copy_certificate, {}) + _assert_restarted_daemons(component.daemons, try_restart) diff --git a/plinth/modules/letsencrypt/views.py b/plinth/modules/letsencrypt/views.py index f6b9906f1..5a946f680 100644 --- a/plinth/modules/letsencrypt/views.py +++ b/plinth/modules/letsencrypt/views.py @@ -11,7 +11,6 @@ from django.urls import reverse_lazy from django.utils.translation import gettext as _ from django.views.decorators.http import require_POST -from plinth.errors import ActionError from plinth.modules import letsencrypt from plinth.views import AppView @@ -41,11 +40,11 @@ def revoke(request, domain): _('Certificate successfully revoked for domain {domain}.' 'This may take a few moments to take effect.').format( domain=domain)) - except ActionError as exception: + except Exception as exception: messages.error( request, _('Failed to revoke certificate for domain {domain}: {error}'). - format(domain=domain, error=exception.args[2])) + format(domain=domain, error=exception.args)) return redirect(reverse_lazy('letsencrypt:index')) @@ -59,11 +58,11 @@ def obtain(request, domain): request, _('Certificate successfully obtained for domain {domain}').format( domain=domain)) - except ActionError as exception: + except Exception as exception: messages.error( request, _('Failed to obtain certificate for domain {domain}: {error}'). - format(domain=domain, error=exception.args[2])) + format(domain=domain, error=exception.args)) return redirect(reverse_lazy('letsencrypt:index')) @@ -76,11 +75,11 @@ def reobtain(request, domain): request, _('Certificate successfully obtained for domain {domain}').format( domain=domain)) - except ActionError as exception: + except Exception as exception: messages.error( request, _('Failed to obtain certificate for domain {domain}: {error}'). - format(domain=domain, error=exception.args[2])) + format(domain=domain, error=exception.args)) return redirect(reverse_lazy('letsencrypt:index')) @@ -93,10 +92,10 @@ def delete(request, domain): request, _('Certificate successfully deleted for domain {domain}').format( domain=domain)) - except ActionError as exception: + except Exception as exception: messages.error( request, _('Failed to delete certificate for domain {domain}: {error}'). - format(domain=domain, error=exception.args[2])) + format(domain=domain, error=exception.args)) return redirect(reverse_lazy('letsencrypt:index')) diff --git a/plinth/modules/matrixsynapse/__init__.py b/plinth/modules/matrixsynapse/__init__.py index c007994df..d1043c19c 100644 --- a/plinth/modules/matrixsynapse/__init__.py +++ b/plinth/modules/matrixsynapse/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure matrix-synapse server. -""" +"""FreedomBox app to configure matrix-synapse server.""" import logging import os @@ -11,7 +9,6 @@ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from ruamel.yaml.util import load_yaml_guess_indent -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import Daemon @@ -23,7 +20,7 @@ from plinth.modules.letsencrypt.components import LetsEncrypt from plinth.package import Packages, install from plinth.utils import format_lazy, is_non_empty_file -from . import manifest +from . import manifest, privileged _description = [ _('Matrix is an new ' @@ -41,16 +38,6 @@ _description = [ logger = logging.getLogger(__name__) -CONF_DIR = "/etc/matrix-synapse/conf.d/" - -ORIG_CONF_PATH = '/etc/matrix-synapse/homeserver.yaml' -SERVER_NAME_PATH = CONF_DIR + 'server_name.yaml' -STATIC_CONF_PATH = CONF_DIR + 'freedombox-static.yaml' -LISTENERS_CONF_PATH = CONF_DIR + 'freedombox-listeners.yaml' -REGISTRATION_CONF_PATH = CONF_DIR + 'freedombox-registration.yaml' -TURN_CONF_PATH = CONF_DIR + 'freedombox-turn.yaml' -OVERRIDDEN_TURN_CONF_PATH = CONF_DIR + 'turn.yaml' - class MatrixSynapseApp(app_module.App): """FreedomBox app for Matrix Synapse.""" @@ -122,7 +109,7 @@ class MatrixSynapseApp(app_module.App): if old_version and old_version < 6: upgrade() else: - actions.superuser_run('matrixsynapse', ['post-install']) + privileged.post_install() if not old_version: self.enable() @@ -144,14 +131,13 @@ class MatrixSynapseTurnConsumer(TurnConsumer): def upgrade(): """Upgrade matrix-synapse configuration to avoid conffile prompt.""" - public_registration_status = get_public_registration_status() - actions.superuser_run('matrixsynapse', ['move-old-conf']) + public_registration_status = privileged.public_registration('status') + privileged.move_old_conf() install(['matrix-synapse'], force_configuration='new', reinstall=True, force_missing_configuration=True) - actions.superuser_run('matrixsynapse', ['post-install']) + privileged.post_install() if public_registration_status: - actions.superuser_run('matrixsynapse', - ['public-registration', 'enable']) + privileged.public_registration('enable') def setup_domain(domain_name): @@ -159,13 +145,12 @@ def setup_domain(domain_name): app = app_module.App.get('matrixsynapse') app.get_component('letsencrypt-matrixsynapse').setup_certificates( [domain_name]) - actions.superuser_run('matrixsynapse', - ['setup', '--domain-name', domain_name]) + privileged.setup(domain_name) def is_setup(): """Return whether the Matrix Synapse server is setup.""" - return os.path.exists(SERVER_NAME_PATH) + return os.path.exists(privileged.SERVER_NAME_PATH) def get_domains(): @@ -182,7 +167,7 @@ def get_configured_domain_name(): if not is_setup(): return None - with open(SERVER_NAME_PATH, encoding='utf-8') as config_file: + with open(privileged.SERVER_NAME_PATH, encoding='utf-8') as config_file: config, _, _ = load_yaml_guess_indent(config_file) return config['server_name'] @@ -190,8 +175,8 @@ def get_configured_domain_name(): def get_turn_configuration() -> (List[str], str, bool): """Return TurnConfiguration if setup else empty.""" - for file_path, managed in ((OVERRIDDEN_TURN_CONF_PATH, False), - (TURN_CONF_PATH, True)): + for file_path, managed in ((privileged.OVERRIDDEN_TURN_CONF_PATH, False), + (privileged.TURN_CONF_PATH, True)): if is_non_empty_file(file_path): with open(file_path, encoding='utf-8') as config_file: config, _, _ = load_yaml_guess_indent(config_file) @@ -202,13 +187,6 @@ def get_turn_configuration() -> (List[str], str, bool): return (TurnConfiguration(), True) -def get_public_registration_status() -> bool: - """Return whether public registration is enabled.""" - output = actions.superuser_run('matrixsynapse', - ['public-registration', 'status']) - return output.strip() == 'enabled' - - def get_certificate_status(): """Return the status of certificate for the configured domain.""" app = app_module.App.get('matrixsynapse') @@ -226,7 +204,4 @@ def update_turn_configuration(config: TurnConfiguration, managed=True, if not force and app.needs_setup(): return - params = ['configure-turn'] - params += ['--managed'] if managed else [] - actions.superuser_run('matrixsynapse', params, - input=config.to_json().encode()) + privileged.configure_turn(managed, config.to_json()) diff --git a/plinth/modules/matrixsynapse/data/etc/fail2ban/filter.d/matrix-auth-freedombox.conf b/plinth/modules/matrixsynapse/data/etc/fail2ban/filter.d/matrix-auth-freedombox.conf new file mode 100644 index 000000000..498135e3d --- /dev/null +++ b/plinth/modules/matrixsynapse/data/etc/fail2ban/filter.d/matrix-auth-freedombox.conf @@ -0,0 +1,7 @@ +[INCLUDES] +before = common.conf + +[Definition] +_daemon = apache-access +prefregex = %(__prefix_line)s +failregex = \S+ - \S+ \[[^\]]*\] "POST /_matrix/client/.*/login HTTP/\S+" 403 diff --git a/plinth/modules/matrixsynapse/data/etc/fail2ban/jail.d/matrix-auth-freedombox.conf b/plinth/modules/matrixsynapse/data/etc/fail2ban/jail.d/matrix-auth-freedombox.conf new file mode 100644 index 000000000..3fb52a559 --- /dev/null +++ b/plinth/modules/matrixsynapse/data/etc/fail2ban/jail.d/matrix-auth-freedombox.conf @@ -0,0 +1,4 @@ +[matrix-auth-freedombox] +enabled = true +port = http,https +journalmatch = SYSLOG_IDENTIFIER=apache-access diff --git a/actions/matrixsynapse b/plinth/modules/matrixsynapse/privileged.py old mode 100755 new mode 100644 similarity index 55% rename from actions/matrixsynapse rename to plinth/modules/matrixsynapse/privileged.py index 75e22368f..d8b98111e --- a/actions/matrixsynapse +++ b/plinth/modules/matrixsynapse/privileged.py @@ -1,24 +1,25 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Matrix-Synapse server. -""" +"""Configure Matrix-Synapse server.""" -import argparse import json import os import pathlib -import sys +from typing import Optional import yaml from plinth import action_utils -from plinth.modules.matrixsynapse import (LISTENERS_CONF_PATH, ORIG_CONF_PATH, - REGISTRATION_CONF_PATH, - STATIC_CONF_PATH) +from plinth.actions import privileged -TURN_CONF_PATH = '/etc/matrix-synapse/conf.d/freedombox-turn.yaml' -OVERRIDDEN_TURN_CONF_PATH = '/etc/matrix-synapse/conf.d/turn.yaml' +CONF_DIR = "/etc/matrix-synapse/conf.d/" + +ORIG_CONF_PATH = '/etc/matrix-synapse/homeserver.yaml' +SERVER_NAME_PATH = CONF_DIR + 'server_name.yaml' +STATIC_CONF_PATH = CONF_DIR + 'freedombox-static.yaml' +LISTENERS_CONF_PATH = CONF_DIR + 'freedombox-listeners.yaml' +REGISTRATION_CONF_PATH = CONF_DIR + 'freedombox-registration.yaml' +TURN_CONF_PATH = CONF_DIR + 'freedombox-turn.yaml' +OVERRIDDEN_TURN_CONF_PATH = CONF_DIR + 'turn.yaml' STATIC_CONFIG = { 'max_upload_size': @@ -40,38 +41,8 @@ STATIC_CONFIG = { } -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('post-install', help='Perform post install steps') - help_pubreg = 'Enable/Disable/Status public user registration.' - pubreg = subparsers.add_parser('public-registration', help=help_pubreg) - pubreg.add_argument('command', choices=('enable', 'disable', 'status'), - help=help_pubreg) - setup = subparsers.add_parser('setup', help='Set domain name for Matrix') - setup.add_argument( - '--domain-name', - help='The domain name that will be used by Matrix Synapse') - - subparsers.add_parser( - 'move-old-conf', - help='Move old configuration file to backup before reinstall') - - turn = subparsers.add_parser( - 'configure-turn', - help='Configure a TURN server for use with Matrix Synapse') - turn.add_argument( - '--managed', required=False, default=False, action='store_true', - help='Whether configuration is provided by user or auto-managed by ' - 'FreedomBox') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_post_install(_): +@privileged +def post_install(): """Perform post installation configuration.""" with open(STATIC_CONF_PATH, 'w', encoding='utf-8') as static_conf_file: yaml.dump(STATIC_CONFIG, static_conf_file) @@ -91,15 +62,19 @@ def subcommand_post_install(_): yaml.dump({'listeners': listeners}, listeners_conf_file) -def subcommand_setup(arguments): +@privileged +def setup(domain_name: str): """Configure the domain name for matrix-synapse package.""" - domain_name = arguments.domain_name action_utils.dpkg_reconfigure('matrix-synapse', {'server-name': domain_name}) -def subcommand_public_registration(argument): +@privileged +def public_registration(command: str) -> Optional[bool]: """Enable/Disable/Status public user registration.""" + if command not in ('enable', 'disable', 'status'): + raise ValueError('Invalid command') + try: with open(REGISTRATION_CONF_PATH, encoding='utf-8') as reg_conf_file: config = yaml.load(reg_conf_file) @@ -112,25 +87,22 @@ def subcommand_public_registration(argument): orig_config.get('enable_registration', False) } - if argument.command == 'status': - if config['enable_registration']: - print('enabled') - return - else: - print('disabled') - return - elif argument.command == 'enable': + if command == 'status': + return bool(config['enable_registration']) + elif command == 'enable': config['enable_registration'] = True - elif argument.command == 'disable': + elif command == 'disable': config['enable_registration'] = False with open(REGISTRATION_CONF_PATH, 'w', encoding='utf-8') as reg_conf_file: yaml.dump(config, reg_conf_file) action_utils.service_try_restart('matrix-synapse') + return None -def subcommand_move_old_conf(_arguments): +@privileged +def move_old_conf(): """Move old configuration to backup so it can be restored by reinstall.""" conf_file = pathlib.Path(ORIG_CONF_PATH) if conf_file.exists(): @@ -138,8 +110,8 @@ def subcommand_move_old_conf(_arguments): conf_file.replace(backup_file) -def _set_turn_config(conf_file): - turn_server_config = json.loads(''.join(sys.stdin)) +def _set_turn_config(conf_file, conf): + turn_server_config = json.loads(conf) if not turn_server_config['uris']: # No valid configuration, remove the configuration file @@ -161,22 +133,12 @@ def _set_turn_config(conf_file): yaml.dump(config, turn_config) -def subcommand_configure_turn(arguments): +@privileged +def configure_turn(managed: bool, conf: str): """Set parameters for the STUN/TURN server to use with Matrix Synapse.""" - if arguments.managed: - _set_turn_config(TURN_CONF_PATH) + if managed: + _set_turn_config(TURN_CONF_PATH, conf) else: - _set_turn_config(OVERRIDDEN_TURN_CONF_PATH) + _set_turn_config(OVERRIDDEN_TURN_CONF_PATH, conf) action_utils.service_try_restart('matrix-synapse') - - -def main(): - arguments = parse_arguments() - sub_command = arguments.subcommand.replace('-', '_') - sub_command_method = globals()['subcommand_' + sub_command] - sub_command_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/matrixsynapse/tests/test_turn_config.py b/plinth/modules/matrixsynapse/tests/test_turn_config.py index 2f48705f0..9971e070b 100644 --- a/plinth/modules/matrixsynapse/tests/test_turn_config.py +++ b/plinth/modules/matrixsynapse/tests/test_turn_config.py @@ -9,8 +9,10 @@ import pytest from plinth.modules import matrixsynapse from plinth.modules.coturn.components import TurnConfiguration +from plinth.modules.matrixsynapse import privileged -actions_name = 'matrixsynapse' +pytestmark = pytest.mark.usefixtures('mock_privileged') +privileged_modules_to_mock = ['plinth.modules.matrixsynapse.privileged'] @pytest.fixture(name='managed_turn_conf_file') @@ -28,29 +30,27 @@ def fixture_overridden_turn_conf_file(tmp_path): @pytest.fixture(autouse=True) -def fixture_set_paths(actions_module, capsys, managed_turn_conf_file, - overridden_turn_conf_file): +def fixture_set_paths(managed_turn_conf_file, overridden_turn_conf_file): """Run actions with custom root path.""" - actions_module.TURN_CONF_PATH = managed_turn_conf_file - actions_module.OVERRIDDEN_TURN_CONF_PATH = overridden_turn_conf_file - with patch('plinth.action_utils.service_try_restart'): + privileged.TURN_CONF_PATH = managed_turn_conf_file + privileged.OVERRIDDEN_TURN_CONF_PATH = overridden_turn_conf_file + with patch('plinth.privileged.service.try_restart'): yield @pytest.fixture(name='test_configuration', autouse=True) -def fixture_test_configuration(call_action, managed_turn_conf_file, +def fixture_test_configuration(managed_turn_conf_file, overridden_turn_conf_file): """Use a separate Matrix Synapse configuration for tests. - Overrides TURN configuration files and patches actions.superuser_run - with the fixture call_action + Overrides TURN configuration files. """ - with (patch('plinth.modules.matrixsynapse.TURN_CONF_PATH', + matrixsynapse = 'plinth.modules.matrixsynapse' + with (patch(f'{matrixsynapse}.privileged.TURN_CONF_PATH', managed_turn_conf_file), - patch('plinth.modules.matrixsynapse.OVERRIDDEN_TURN_CONF_PATH', + patch(f'{matrixsynapse}.privileged.OVERRIDDEN_TURN_CONF_PATH', overridden_turn_conf_file), - patch('plinth.modules.matrixsynapse.is_setup', return_value=True), - patch('plinth.actions.superuser_run', call_action), + patch(f'{matrixsynapse}.is_setup', return_value=True), patch('plinth.app.App.get') as app_get): app = Mock() app_get.return_value = app @@ -71,15 +71,15 @@ updated_coturn_configuration = TurnConfiguration( 'aiP02OsbkC7BUeKvKzhAsTZ8MEwMd3yTwpr2uvbOxgWe51AGyOlj6WGuCyqj7iaO') -def _set_managed_configuration(monkeypatch, config=coturn_configuration): - monkeypatch.setattr('sys.stdin', config.to_json()) - matrixsynapse.update_turn_configuration(config) +def _set_managed_configuration(config=coturn_configuration): + with patch('plinth.action_utils.service_try_restart'): + matrixsynapse.update_turn_configuration(config) -def _set_overridden_configuration(monkeypatch, +def _set_overridden_configuration( config=overridden_configuration): - monkeypatch.setattr('sys.stdin', config.to_json()) - matrixsynapse.update_turn_configuration(config, managed=False) + with patch('plinth.action_utils.service_try_restart'): + matrixsynapse.update_turn_configuration(config, managed=False) def _assert_conf(expected_configuration, expected_managed): @@ -90,30 +90,30 @@ def _assert_conf(expected_configuration, expected_managed): assert managed == expected_managed -def test_managed_turn_server_configuration(monkeypatch): +def test_managed_turn_server_configuration(): """Test setting and getting managed TURN server configuration.""" - _set_managed_configuration(monkeypatch) + _set_managed_configuration() _assert_conf(coturn_configuration, True) -def test_overridden_turn_server_configuration(monkeypatch): +def test_overridden_turn_server_configuration(): """Test setting and getting overridden TURN sever configuration.""" - _set_overridden_configuration(monkeypatch) + _set_overridden_configuration() _assert_conf(overridden_configuration, False) -def test_revert_to_managed_turn_server_configuration(monkeypatch): +def test_revert_to_managed_turn_server_configuration(): """Test setting and getting overridden TURN sever configuration.""" # Had to do all 3 operations because all fixtures were function-scoped - _set_managed_configuration(monkeypatch) - _set_overridden_configuration(monkeypatch) - _set_overridden_configuration(monkeypatch, TurnConfiguration()) + _set_managed_configuration() + _set_overridden_configuration() + _set_overridden_configuration(TurnConfiguration()) _assert_conf(coturn_configuration, True) -def test_coturn_configuration_update_after_admin_override(monkeypatch): +def test_coturn_configuration_update_after_admin_override(): """Test that overridden conf prevails even if managed conf is updated.""" - _set_managed_configuration(monkeypatch) - _set_overridden_configuration(monkeypatch) - _set_managed_configuration(monkeypatch, updated_coturn_configuration) + _set_managed_configuration() + _set_overridden_configuration() + _set_managed_configuration(updated_coturn_configuration) _assert_conf(overridden_configuration, False) diff --git a/plinth/modules/matrixsynapse/views.py b/plinth/modules/matrixsynapse/views.py index 3d8ba9a30..ad47b6de7 100644 --- a/plinth/modules/matrixsynapse/views.py +++ b/plinth/modules/matrixsynapse/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the Matrix Synapse module. -""" +"""Views for the Matrix Synapse module.""" from django.contrib import messages from django.shortcuts import redirect @@ -9,19 +7,19 @@ from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic import FormView -from plinth import actions from plinth import app as app_module from plinth.forms import DomainSelectionForm from plinth.modules import matrixsynapse, names from plinth.modules.coturn.components import TurnConfiguration from plinth.views import AppView -from . import get_public_registration_status, get_turn_configuration +from . import get_turn_configuration, privileged from .forms import MatrixSynapseForm class SetupView(FormView): """Show matrix-synapse setup page.""" + template_name = 'matrix-synapse-pre-setup.html' form_class = DomainSelectionForm success_url = reverse_lazy('matrixsynapse:index') @@ -46,6 +44,7 @@ class SetupView(FormView): class MatrixSynapseAppView(AppView): """Show matrix-synapse service page.""" + app_id = 'matrixsynapse' template_name = 'matrix-synapse.html' form_class = MatrixSynapseForm @@ -69,21 +68,24 @@ class MatrixSynapseAppView(AppView): initial = super().get_initial() config, managed = get_turn_configuration() initial.update({ - 'enable_public_registration': get_public_registration_status(), - 'enable_managed_turn': managed, - 'turn_uris': '\n'.join(config.uris), - 'shared_secret': config.shared_secret + 'enable_public_registration': + privileged.public_registration('status'), + 'enable_managed_turn': + managed, + 'turn_uris': + '\n'.join(config.uris), + 'shared_secret': + config.shared_secret }) return initial @staticmethod def _handle_public_registrations(new_config): + if new_config['enable_public_registration']: - actions.superuser_run('matrixsynapse', - ['public-registration', 'enable']) + privileged.public_registration('enable') else: - actions.superuser_run('matrixsynapse', - ['public-registration', 'disable']) + privileged.public_registration('disable') @staticmethod def _handle_turn_configuration(old_config, new_config): diff --git a/plinth/modules/mediawiki/__init__.py b/plinth/modules/mediawiki/__init__.py index b2575cb4a..0a9537f8e 100644 --- a/plinth/modules/mediawiki/__init__.py +++ b/plinth/modules/mediawiki/__init__.py @@ -1,14 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure MediaWiki. -""" +"""FreedomBox app to configure MediaWiki.""" import re from urllib.parse import urlparse from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import Daemon @@ -17,7 +14,7 @@ from plinth.modules.backups.components import BackupRestore from plinth.modules.firewall.components import Firewall from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia ' @@ -96,8 +93,8 @@ class MediaWikiApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('mediawiki', ['setup']) - actions.superuser_run('mediawiki', ['update']) + privileged.setup() + privileged.update() self.enable() @@ -107,20 +104,7 @@ class Shortcut(frontpage.Shortcut): def enable(self): """When enabled, check if MediaWiki is in private mode.""" super().enable() - self.login_required = is_private_mode_enabled() - - -def is_public_registration_enabled(): - """Return whether public registration is enabled.""" - output = actions.superuser_run('mediawiki', - ['public-registrations', 'status']) - return output.strip() == 'enabled' - - -def is_private_mode_enabled(): - """Return whether private mode is enabled or disabled.""" - output = actions.superuser_run('mediawiki', ['private-mode', 'status']) - return output.strip() == 'enabled' + self.login_required = privileged.private_mode('status') def _get_config_value_in_file(setting_name, config_file): @@ -144,11 +128,6 @@ def get_default_skin(): return _get_config_value('$wgDefaultSkin') -def set_default_skin(skin): - """Set the value of the default skin.""" - actions.superuser_run('mediawiki', ['set-default-skin', skin]) - - def get_server_url(): """Return the value of the server URL.""" server_url = _get_config_value('$wgServer') @@ -161,15 +140,9 @@ def set_server_url(domain): if domain.endswith('.onion'): protocol = 'http' - actions.superuser_run('mediawiki', - ['set-server-url', f'{protocol}://{domain}']) + privileged.set_server_url(f'{protocol}://{domain}') def get_site_name(): """Return the value of MediaWiki's site name.""" return _get_config_value('$wgSitename') or 'Wiki' - - -def set_site_name(site_name): - """Set the value of $wgSitename.""" - actions.superuser_run('mediawiki', ['set-site-name', site_name]) diff --git a/actions/mediawiki b/plinth/modules/mediawiki/privileged.py old mode 100755 new mode 100644 similarity index 51% rename from actions/mediawiki rename to plinth/modules/mediawiki/privileged.py index bf3fcd9a3..d011f37e0 --- a/actions/mediawiki +++ b/plinth/modules/mediawiki/privileged.py @@ -1,15 +1,12 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for MediaWiki. -""" +"""Configure MediaWiki.""" -import argparse import os import subprocess -import sys import tempfile +from typing import Optional +from plinth.actions import privileged from plinth.utils import generate_password MAINTENANCE_SCRIPTS_DIR = "/usr/share/mediawiki/maintenance" @@ -17,49 +14,6 @@ CONF_FILE = '/etc/mediawiki/FreedomBoxSettings.php' LOCAL_SETTINGS_CONF = '/etc/mediawiki/LocalSettings.php' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Setup MediaWiki') - subparsers.add_parser('update', help='Run MediaWiki update script') - - help_pub_reg = 'Enable/Disable/Status public user registration.' - pub_reg = subparsers.add_parser('public-registrations', help=help_pub_reg) - pub_reg.add_argument('command', choices=('enable', 'disable', 'status'), - help=help_pub_reg) - - 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'), - help=help_private_mode) - - change_password = subparsers.add_parser('change-password', - help='Change user password') - change_password.add_argument('--username', default='admin', - help='name of the MediaWiki user') - change_password.add_argument('--password', - help='new password for the MediaWiki user') - - default_skin = subparsers.add_parser('set-default-skin', - help='Set the default skin') - default_skin.add_argument('skin', help='name of the skin') - - server_url = subparsers.add_parser( - 'set-server-url', help='Set the value of $wgServer for this server') - server_url.add_argument('server_url', help='value of $wgServer') - - site_name = subparsers.add_parser( - 'set-site-name', help='Set the value of $wgSitename for this Wiki') - site_name.add_argument('site_name', help='value of $wgSitename') - - subparsers.required = True - return parser.parse_args() - - def _get_php_command(): """Return the PHP command that should be used on CLI. @@ -82,7 +36,8 @@ def _get_php_command(): return f'php{version}' -def subcommand_setup(_): +@privileged +def setup(): """Run the installer script to create database and configuration file.""" data_dir = '/var/lib/mediawiki-db/' if not os.path.exists(data_dir): @@ -103,10 +58,10 @@ def subcommand_setup(_): ]) subprocess.run(['chmod', '-R', 'o-rwx', data_dir], check=True) subprocess.run(['chown', '-R', 'www-data:www-data', data_dir], check=True) - include_custom_config() + _include_custom_config() -def include_custom_config(): +def _include_custom_config(): """Include FreedomBox specific configuration in LocalSettings.php.""" with open(LOCAL_SETTINGS_CONF, 'r', encoding='utf-8') as conf_file: lines = conf_file.readlines() @@ -133,26 +88,30 @@ def include_custom_config(): conf_file.writelines(lines) -def subcommand_change_password(arguments): - """Change the password for a given user""" - new_password = ''.join(sys.stdin) +@privileged +def change_password(username: str, password: str): + """Change the password for a given user.""" change_password_script = os.path.join(MAINTENANCE_SCRIPTS_DIR, 'changePassword.php') subprocess.check_call([ - _get_php_command(), change_password_script, '--user', - arguments.username, '--password', new_password + _get_php_command(), change_password_script, '--user', username, + '--password', password ]) -def subcommand_update(_): +@privileged +def update(): """Run update.php maintenance script when version upgrades happen.""" update_script = os.path.join(MAINTENANCE_SCRIPTS_DIR, 'update.php') subprocess.check_call([_get_php_command(), update_script, '--quick']) -def subcommand_public_registrations(arguments): +@privileged +def public_registrations(command: str) -> Optional[bool]: """Enable or Disable public registrations for MediaWiki.""" + if command not in ('enable', 'disable', 'status'): + raise ValueError('Invalid command') with open(CONF_FILE, 'r', encoding='utf-8') as conf_file: lines = conf_file.readlines() @@ -160,28 +119,31 @@ def subcommand_public_registrations(arguments): def is_pub_reg_line(line): return line.startswith("$wgGroupPermissions['*']['createaccount']") - if arguments.command == 'status': + if command == 'status': conf_lines = list(filter(is_pub_reg_line, lines)) - if conf_lines: - print('enabled' if 'true' in conf_lines[0] else 'disabled') - else: - print('disabled') - else: - with open(CONF_FILE, 'w', encoding='utf-8') as conf_file: - for line in lines: - if is_pub_reg_line(line): - words = line.split() - if arguments.command == 'enable': - words[-1] = 'true;' - else: - words[-1] = 'false;' - conf_file.write(" ".join(words) + '\n') + return bool(conf_lines and 'true' in conf_lines[0]) + + with open(CONF_FILE, 'w', encoding='utf-8') as conf_file: + for line in lines: + if is_pub_reg_line(line): + words = line.split() + if command == 'enable': + words[-1] = 'true;' else: - conf_file.write(line) + words[-1] = 'false;' + conf_file.write(" ".join(words) + '\n') + else: + conf_file.write(line) + + return None -def subcommand_private_mode(arguments): - """Enable or Disable Private mode for wiki""" +@privileged +def private_mode(command: str): + """Enable or Disable Private mode for wiki.""" + if command not in ('enable', 'disable', 'status'): + raise ValueError('Invalid command') + with open(CONF_FILE, 'r', encoding='utf-8') as conf_file: lines = conf_file.readlines() @@ -189,25 +151,22 @@ def subcommand_private_mode(arguments): return line.startswith("$wgGroupPermissions['*']['read']") read_conf_lines = list(filter(is_read_line, lines)) - if arguments.command == 'status': - if read_conf_lines and 'false' in read_conf_lines[0]: - print('enabled') - else: - print('disabled') - else: - with open(CONF_FILE, 'w', encoding='utf-8') as conf_file: - conf_value = 'false;' if arguments.command == 'enable' else 'true;' - for line in lines: - if is_read_line(line): - words = line.split() - words[-1] = conf_value - conf_file.write(" ".join(words) + '\n') - else: - conf_file.write(line) + if command == 'status': + return (read_conf_lines and 'false' in read_conf_lines[0]) - if not read_conf_lines: - conf_file.write("$wgGroupPermissions['*']['read'] = " + - conf_value + '\n') + with open(CONF_FILE, 'w', encoding='utf-8') as conf_file: + conf_value = 'false;' if command == 'enable' else 'true;' + for line in lines: + if is_read_line(line): + words = line.split() + words[-1] = conf_value + conf_file.write(" ".join(words) + '\n') + else: + conf_file.write(line) + + if not read_conf_lines: + conf_file.write("$wgGroupPermissions['*']['read'] = " + + conf_value + '\n') def _update_setting(setting_name, setting_line): @@ -229,31 +188,20 @@ def _update_setting(setting_name, setting_line): conf_file.writelines(lines) -def subcommand_set_default_skin(arguments): +@privileged +def set_default_skin(skin: str): """Set a default skin.""" - skin = arguments.skin _update_setting('$wgDefaultSkin ', f'$wgDefaultSkin = "{skin}";\n') -def subcommand_set_server_url(arguments): +@privileged +def set_server_url(server_url: str): """Set the value of $wgServer for this MediaWiki server.""" # This is a required setting from MediaWiki 1.34 - _update_setting('$wgServer', f'$wgServer = "{arguments.server_url}";\n') + _update_setting('$wgServer', f'$wgServer = "{server_url}";\n') -def subcommand_set_site_name(arguments): +@privileged +def set_site_name(site_name: str): """Set the value of $wgSitename for this MediaWiki server.""" - _update_setting('$wgSitename', f'$wgSitename = "{arguments.site_name}";\n') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() + _update_setting('$wgSitename', f'$wgSitename = "{site_name}";\n') diff --git a/plinth/modules/mediawiki/tests/test_functional.py b/plinth/modules/mediawiki/tests/test_functional.py index 768521950..19a6a5523 100644 --- a/plinth/modules/mediawiki/tests/test_functional.py +++ b/plinth/modules/mediawiki/tests/test_functional.py @@ -25,9 +25,21 @@ class TestMediawikiApp(functional.BaseAppTests): """Setup the app.""" functional.login(session_browser) functional.install(session_browser, 'mediawiki') + functional.app_enable(session_browser, 'mediawiki') _set_domain(session_browser) + _set_admin_password(session_browser, 'whatever123') - def test_public_registrations(self, session_browser): + @pytest.fixture(name='no_login') + def fixture_no_login(self, session_browser): + """Ensure logout from MediaWiki.""" + _logout(session_browser) + + @pytest.fixture(name='login') + def fixture_login(self, session_browser): + """Ensure login to MediaWiki.""" + _login_with_credentials(session_browser, 'admin', 'whatever123') + + def test_public_registrations(self, session_browser, no_login): """Test enabling public registrations.""" _enable_public_registrations(session_browser) _verify_create_account_link(session_browser) @@ -35,7 +47,7 @@ class TestMediawikiApp(functional.BaseAppTests): _disable_public_registrations(session_browser) _verify_no_create_account_link(session_browser) - def test_private_mode(self, session_browser): + def test_private_mode(self, session_browser, no_login): """Test enabling private mode.""" _enable_private_mode(session_browser) _verify_no_create_account_link(session_browser) @@ -44,7 +56,8 @@ class TestMediawikiApp(functional.BaseAppTests): _disable_private_mode(session_browser) _verify_anonymous_reads_edits_link(session_browser) - def test_private_mode_public_registrations(self, session_browser): + def test_private_mode_public_registrations(self, session_browser, + no_login): """Test interactive between private mode and public registrations. Requires JS.""" @@ -58,25 +71,18 @@ class TestMediawikiApp(functional.BaseAppTests): _enable_public_registrations(session_browser) _verify_create_account_link(session_browser) - def test_upload_files(self, session_browser): - """Test that logged in user can see upload files option. - - Requires JS.""" - _set_admin_password(session_browser, 'whatever123') - _login_with_credentials(session_browser, 'admin', 'whatever123') - - def test_upload_images(self, session_browser): + def test_upload_images(self, session_browser, login): """Test uploading an image.""" _upload_image(session_browser, 'admin', 'whatever123', 'noise.png') assert _image_exists(session_browser, 'Noise.png') - def test_upload_svg_image(self, session_browser): + def test_upload_svg_image(self, session_browser, login): """Test uploading an SVG image.""" _upload_image(session_browser, 'admin', 'whatever123', 'apps-background.svg') assert _image_exists(session_browser, 'Apps-background.svg') - def test_backup_restore(self, session_browser): + def test_backup_restore(self, session_browser, login): """Test backup and restore of pages and images.""" if not _image_exists(session_browser, 'Noise.png'): _upload_image(session_browser, 'admin', 'whatever123', 'Noise.png') @@ -147,19 +153,19 @@ def _verify_no_create_account_link(browser): lambda: not _is_create_account_available(browser)) -def _is_anonymouse_read_allowed(browser): +def _is_anonymous_read_allowed(browser): """Load the main page and check if anonymous reading is allowed.""" functional.visit(browser, '/mediawiki') return browser.is_element_present_by_id('ca-nstab-main') def _verify_anonymous_reads_edits_link(browser): - assert functional.eventually(_is_anonymouse_read_allowed, args=[browser]) + assert functional.eventually(_is_anonymous_read_allowed, args=[browser]) def _verify_no_anonymous_reads_edits_link(browser): assert functional.eventually( - lambda: not _is_anonymouse_read_allowed(browser)) + lambda: not _is_anonymous_read_allowed(browser)) assert browser.is_element_present_by_id('ca-nstab-special') @@ -179,6 +185,13 @@ def _login_with_credentials(browser, username, password): args=['t-upload']) +def _logout(browser): + """Logout from MediaWiki.""" + functional.visit(browser, '/mediawiki/Special:UserLogout') + if browser.find_by_css('#bodyContent form'): + functional.submit(browser, form_class='oo-ui-formLayout') + + def _upload_image(browser, username, password, image, ignore_warnings=True): """Upload an image to MediaWiki. Idempotent.""" functional.visit(browser, '/mediawiki') diff --git a/plinth/modules/mediawiki/tests/test_settings.py b/plinth/modules/mediawiki/tests/test_settings.py index 2bd9b0644..20d0c9e4a 100644 --- a/plinth/modules/mediawiki/tests/test_settings.py +++ b/plinth/modules/mediawiki/tests/test_settings.py @@ -10,15 +10,17 @@ from unittest.mock import patch import pytest from plinth.modules import mediawiki +from plinth.modules.mediawiki import privileged -actions_name = 'mediawiki' +pytestmark = pytest.mark.usefixtures('mock_privileged') current_directory = pathlib.Path(__file__).parent +privileged_modules_to_mock = ['plinth.modules.mediawiki.privileged'] @pytest.fixture(autouse=True) -def fixture_setup_configuration(actions_module, conf_file): +def fixture_setup_configuration(conf_file): """Set configuration file path in actions module.""" - actions_module.CONF_FILE = conf_file + privileged.CONF_FILE = conf_file @pytest.fixture(name='conf_file') @@ -34,12 +36,11 @@ def fixture_conf_file(tmp_path): @pytest.fixture(name='test_configuration', autouse=True) -def fixture_test_configuration(call_action, conf_file): +def fixture_test_configuration(conf_file): """Use a separate MediaWiki configuration for tests. Uses local FreedomBoxStaticSettings.php, a temp version of - FreedomBoxSettings.php and patches actions.superuser_run with the fixture - call_action + FreedomBoxSettings.php """ data_directory = pathlib.Path(__file__).parent.parent / 'data' @@ -47,8 +48,7 @@ def fixture_test_configuration(call_action, conf_file): mediawiki.STATIC_CONFIG_FILE.split('/')[-1]) with patch('plinth.modules.mediawiki.STATIC_CONFIG_FILE', static_config_file), \ - patch('plinth.modules.mediawiki.USER_CONFIG_FILE', conf_file), \ - patch('plinth.actions.superuser_run', call_action): + patch('plinth.modules.mediawiki.USER_CONFIG_FILE', conf_file): yield @@ -56,7 +56,7 @@ def test_default_skin(): """Test getting and setting the default skin.""" assert mediawiki.get_default_skin() == 'timeless' new_skin = 'vector' - mediawiki.set_default_skin(new_skin) + privileged.set_default_skin(new_skin) assert mediawiki.get_default_skin() == new_skin @@ -72,5 +72,5 @@ def test_site_name(): """Test getting and setting $wgSitename.""" assert mediawiki.get_site_name() == 'Wiki' new_site_name = 'My MediaWiki' - mediawiki.set_site_name(new_site_name) + privileged.set_site_name(new_site_name) assert mediawiki.get_site_name() == new_site_name diff --git a/plinth/modules/mediawiki/views.py b/plinth/modules/mediawiki/views.py index 15e3e7b06..f08b5e789 100644 --- a/plinth/modules/mediawiki/views.py +++ b/plinth/modules/mediawiki/views.py @@ -1,21 +1,16 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring MediaWiki. -""" +"""FreedomBox app for configuring MediaWiki.""" import logging from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions from plinth import app as app_module from plinth import views -from plinth.errors import ActionError from plinth.modules import mediawiki -from . import (get_default_skin, get_server_url, get_site_name, - is_private_mode_enabled, is_public_registration_enabled) +from . import get_default_skin, get_server_url, get_site_name, privileged from .forms import MediaWikiForm logger = logging.getLogger(__name__) @@ -23,6 +18,7 @@ logger = logging.getLogger(__name__) class MediaWikiAppView(views.AppView): """App configuration page.""" + app_id = 'mediawiki' form_class = MediaWikiForm template_name = 'mediawiki.html' @@ -31,11 +27,16 @@ class MediaWikiAppView(views.AppView): """Return the values to fill in the form.""" initial = super().get_initial() initial.update({ - 'enable_public_registrations': is_public_registration_enabled(), - 'enable_private_mode': is_private_mode_enabled(), - 'default_skin': get_default_skin(), - 'domain': get_server_url(), - 'site_name': get_site_name() + 'enable_public_registrations': + privileged.public_registrations('status'), + 'enable_private_mode': + privileged.private_mode('status'), + 'default_skin': + get_default_skin(), + 'domain': + get_server_url(), + 'site_name': + get_site_name() }) return initial @@ -49,10 +50,9 @@ class MediaWikiAppView(views.AppView): if new_config['password']: try: - actions.superuser_run('mediawiki', ['change-password'], - input=new_config['password'].encode()) + privileged.change_password('admin', new_config['password']) messages.success(self.request, _('Password updated')) - except ActionError as exception: + except Exception as exception: logger.exception('Failed to update password: %s', exception) messages.error( self.request, @@ -63,8 +63,7 @@ class MediaWikiAppView(views.AppView): # note action public-registration restarts, if running now if new_config['enable_public_registrations']: if not new_config['enable_private_mode']: - actions.superuser_run('mediawiki', - ['public-registrations', 'enable']) + privileged.public_registrations('enable') messages.success(self.request, _('Public registrations enabled')) else: @@ -72,21 +71,19 @@ class MediaWikiAppView(views.AppView): self.request, 'Public registrations ' + 'cannot be enabled when private mode is enabled') else: - actions.superuser_run('mediawiki', - ['public-registrations', 'disable']) + privileged.public_registrations('disable') messages.success(self.request, _('Public registrations disabled')) if is_changed('enable_private_mode'): if new_config['enable_private_mode']: - actions.superuser_run('mediawiki', ['private-mode', 'enable']) + privileged.private_mode('enable') messages.success(self.request, _('Private mode enabled')) if new_config['enable_public_registrations']: # If public registrations are enabled, then disable it - actions.superuser_run('mediawiki', - ['public-registrations', 'disable']) + privileged.public_registrations('disable') else: - actions.superuser_run('mediawiki', ['private-mode', 'disable']) + privileged.private_mode('disable') messages.success(self.request, _('Private mode disabled')) app = app_module.App.get('mediawiki') @@ -94,7 +91,7 @@ class MediaWikiAppView(views.AppView): shortcut.login_required = new_config['enable_private_mode'] if is_changed('default_skin'): - mediawiki.set_default_skin(new_config['default_skin']) + privileged.set_default_skin(new_config['default_skin']) messages.success(self.request, _('Default skin changed')) if is_changed('domain'): @@ -102,7 +99,7 @@ class MediaWikiAppView(views.AppView): messages.success(self.request, _('Domain name updated')) if is_changed('site_name'): - mediawiki.set_site_name(new_config['site_name']) + privileged.set_site_name(new_config['site_name']) messages.success(self.request, _('Site name updated')) return super().form_valid(form) diff --git a/plinth/modules/minetest/__init__.py b/plinth/modules/minetest/__init__.py index 87f112a1a..ada63c7eb 100644 --- a/plinth/modules/minetest/__init__.py +++ b/plinth/modules/minetest/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for Minetest server. -""" +"""FreedomBox app for Minetest server.""" import augeas from django.urls import reverse_lazy diff --git a/plinth/modules/minetest/privileged.py b/plinth/modules/minetest/privileged.py new file mode 100644 index 000000000..ceae1812f --- /dev/null +++ b/plinth/modules/minetest/privileged.py @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure Minetest server.""" + +from typing import Optional + +import augeas + +from plinth import action_utils +from plinth.actions import privileged + +CONFIG_FILE = '/etc/minetest/minetest.conf' +AUG_PATH = '/files' + CONFIG_FILE + '/.anon' + + +@privileged +def configure(max_players: Optional[int] = None, + enable_pvp: Optional[bool] = None, + creative_mode: Optional[bool] = None, + enable_damage: Optional[bool] = None): + """Update configuration file and restart daemon if necessary.""" + aug = load_augeas() + if max_players is not None: + aug.set(AUG_PATH + '/max_users', str(max_players)) + + if enable_pvp is not None: + aug.set(AUG_PATH + '/enable_pvp', str(enable_pvp).lower()) + + if creative_mode is not None: + aug.set(AUG_PATH + '/creative_mode', str(creative_mode).lower()) + + if enable_damage is not None: + aug.set(AUG_PATH + '/enable_damage', str(enable_damage).lower()) + + aug.save() + action_utils.service_try_restart('minetest-server') + + +def load_augeas(): + """Initialize Augeas.""" + 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() + return aug diff --git a/plinth/modules/minetest/views.py b/plinth/modules/minetest/views.py index 8e9757933..dd347dc2e 100644 --- a/plinth/modules/minetest/views.py +++ b/plinth/modules/minetest/views.py @@ -1,21 +1,19 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for minetest module. -""" +"""Views for minetest module.""" from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth.modules import names from plinth.views import AppView -from . import get_configuration +from . import get_configuration, privileged from .forms import MinetestForm class MinetestAppView(AppView): # pylint: disable=too-many-ancestors """A specialized view for configuring minetest.""" + app_id = 'minetest' template_name = 'minetest.html' form_class = MinetestForm @@ -37,35 +35,23 @@ class MinetestAppView(AppView): # pylint: disable=too-many-ancestors """Change the configurations of Minetest service.""" data = form.cleaned_data old_config = get_configuration() - updated = False + changes = {} if old_config['max_players'] != data['max_players'] \ and data['max_players'] is not None: - actions.superuser_run( - 'minetest', - ['configure', '--max_players', - str(data['max_players'])]) - updated = True + changes['max_players'] = data['max_players'] if old_config['creative_mode'] != data['creative_mode']: - value = 'true' if data['creative_mode'] else 'false' - actions.superuser_run('minetest', - ['configure', '--creative_mode', value]) - updated = True + changes['creative_mode'] = data['creative_mode'] if old_config['enable_pvp'] != data['enable_pvp']: - value = 'true' if data['enable_pvp'] else 'false' - actions.superuser_run('minetest', - ['configure', '--enable_pvp', value]) - updated = True + changes['enable_pvp'] = data['enable_pvp'] if old_config['enable_damage'] != data['enable_damage']: - value = 'true' if data['enable_damage'] else 'false' - actions.superuser_run('minetest', - ['configure', '--enable_damage', value]) - updated = True + changes['enable_damage'] = data['enable_damage'] - if updated: + if changes: + privileged.configure(**changes) messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/minidlna/__init__.py b/plinth/modules/minidlna/__init__.py index 8dc6c462b..e378d8d3b 100644 --- a/plinth/modules/minidlna/__init__.py +++ b/plinth/modules/minidlna/__init__.py @@ -4,7 +4,6 @@ FreedomBox app to configure minidlna. """ from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import Daemon @@ -15,7 +14,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages, install from plinth.utils import Version -from . import manifest +from . import manifest, privileged _description = [ _('MiniDLNA is a simple media server software, with the aim of being ' @@ -30,13 +29,14 @@ _description = [ class MiniDLNAApp(app_module.App): - """Freedombox app managing miniDlna""" + """Freedombox app managing miniDlna.""" + app_id = 'minidlna' _version = 2 def __init__(self): - """Initialize the app components""" + """Initialize the app components.""" super().__init__() groups = {'minidlna': _('Media streaming server')} @@ -75,7 +75,7 @@ class MiniDLNAApp(app_module.App): self.add(firewall) webserver = Webserver('webserver-minidlna', 'minidlna-freedombox', - urls=['http://localhost:8200/']) + urls=['https://{host}/_minidlna/']) self.add(webserver) daemon = Daemon('daemon-minidlna', 'minidlna') @@ -92,7 +92,7 @@ class MiniDLNAApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('minidlna', ['setup']) + privileged.setup() if not old_version: self.enable() @@ -106,18 +106,8 @@ class MiniDLNAApp(app_module.App): if Version(package['new_version']) > Version('1.4~'): return False - media_dir = get_media_dir() + media_dir = privileged.get_media_dir() install(['minidlna'], force_configuration='new') - set_media_dir(media_dir) + privileged.set_media_dir(media_dir) return True - - -def get_media_dir(): - """Return the currently set media directory.""" - return actions.superuser_run('minidlna', ['get-media-dir']) - - -def set_media_dir(media_dir): - """Set the media directory from which files will be scanned for sharing.""" - actions.superuser_run('minidlna', ['set-media-dir', '--dir', media_dir]) diff --git a/actions/minidlna b/plinth/modules/minidlna/privileged.py old mode 100755 new mode 100644 similarity index 58% rename from actions/minidlna rename to plinth/modules/minidlna/privileged.py index e742c52af..2fba83493 --- a/actions/minidlna +++ b/plinth/modules/minidlna/privileged.py @@ -1,9 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration actions for the minidlna server. -""" -import argparse +"""Configure minidlna server.""" + import subprocess from os import chmod, fdopen, remove, stat from shutil import move @@ -12,6 +9,7 @@ from tempfile import mkstemp import augeas from plinth import action_utils +from plinth.actions import privileged from plinth.utils import grep CONFIG_PATH = '/etc/minidlna.conf' @@ -22,23 +20,6 @@ fs.inotify.max_user_watches = 100000 ''' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Setup SSH server') - - subparsers.add_parser('get-media-dir', help='Get media directory') - - set_media_dir = subparsers.add_parser('set-media-dir', - help='Set custom media directory') - set_media_dir.add_argument('--dir') - - subparsers.required = True - return parser.parse_args() - - def _undo_old_configuration_changes(): """Restore /etc/sysctl.conf to before our changes. @@ -59,10 +40,11 @@ def _undo_old_configuration_changes(): aug.save() -def subcommand_setup(_): - """ - Increase inotify watches per folder to allow minidlna to - monitor changes in large media-dirs. +@privileged +def setup(): + """Increase inotify watches per folder. + + This is to allow minidlna to monitor changes in large media-dirs. """ _undo_old_configuration_changes() with open('/etc/sysctl.d/50-freedombox-minidlna.conf', 'w', @@ -72,29 +54,31 @@ def subcommand_setup(_): subprocess.run(['systemctl', 'restart', 'systemd-sysctl'], check=True) -def subcommand_get_media_dir(_): - """Retrieve media directory from minidlna.conf""" +@privileged +def get_media_dir() -> str: + """Retrieve media directory from minidlna.conf.""" line = grep('^media_dir=', CONFIG_PATH) - - print(line[0].split("=")[1]) + return line[0].split('=')[1] -def subcommand_set_media_dir(arguments): - """Set media directory in minidlna.conf""" +@privileged +def set_media_dir(media_dir: str): + """Set media directory in minidlna.conf.""" line = grep('^media_dir=', CONFIG_PATH)[0] - new_line = 'media_dir=%s\n' % arguments.dir + new_line = 'media_dir=%s\n' % media_dir replace_in_config_file(CONFIG_PATH, line, new_line) if action_utils.service_is_running('minidlna'): action_utils.service_restart('minidlna') def replace_in_config_file(file_path, pattern, subst): - """ - Create a temporary minidlna.conf file, - replace the media dir config, - remove original one and move the temporary file. - Preserve permissions as the original file. + """Replace a directive in configuration file. + + - Create a temporary minidlna.conf file + - Replace the media dir config + - Remove original one and move the temporary file + - Preserve permissions as the original file """ temp_file, temp_file_path = mkstemp() with fdopen(temp_file, 'w') as new_file: @@ -106,16 +90,3 @@ def replace_in_config_file(file_path, pattern, subst): remove(file_path) move(temp_file_path, file_path) chmod(file_path, old_st_mode) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/minidlna/views.py b/plinth/modules/minidlna/views.py index 91c24a55c..16f58fdfa 100644 --- a/plinth/modules/minidlna/views.py +++ b/plinth/modules/minidlna/views.py @@ -1,31 +1,31 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the minidlna module -""" +"""Views for the minidlna module.""" + import os from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from plinth.modules import minidlna from plinth.views import AppView +from . import privileged from .forms import MiniDLNAServerForm class MiniDLNAAppView(AppView): + """Show minidlna app view.""" + app_id = 'minidlna' form_class = MiniDLNAServerForm def get_initial(self): - """Initial form value as found in the minidlna.conf""" + """Return initial values of the form.""" initial = super().get_initial() - initial.update({'media_dir': minidlna.get_media_dir()}) - + initial.update({'media_dir': privileged.get_media_dir()}) return initial def form_valid(self, form): - """Apply changes from the form""" + """Apply changes from the form.""" old_config = form.initial new_config = form.cleaned_data @@ -34,7 +34,7 @@ class MiniDLNAAppView(AppView): messages.error(self.request, _('Specified directory does not exist.')) else: - minidlna.set_media_dir(new_config['media_dir']) + privileged.set_media_dir(new_config['media_dir']) messages.success(self.request, _('Updated media directory')) return super().form_valid(form) diff --git a/plinth/modules/networks/__init__.py b/plinth/modules/networks/__init__.py index 3e7252428..6bda322df 100644 --- a/plinth/modules/networks/__init__.py +++ b/plinth/modules/networks/__init__.py @@ -1,18 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to interface with network-manager. -""" +"""FreedomBox app to interface with network-manager.""" import subprocess from logging import Logger from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import daemon, kvstore, menu, network from plinth.package import Packages +from . import privileged + first_boot_steps = [ { 'id': 'network_topology_wizard', @@ -83,7 +82,7 @@ class NetworksApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('networks') + privileged.setup() self.enable() diff --git a/plinth/modules/networks/privileged.py b/plinth/modules/networks/privileged.py new file mode 100644 index 000000000..2ea77518e --- /dev/null +++ b/plinth/modules/networks/privileged.py @@ -0,0 +1,189 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure network manager. + +During initial setup, configure networking for all wired and wireless devices +by creating network manager connections. +""" + +import collections +import itertools +import logging +import re +import subprocess + +from plinth import action_utils +from plinth.actions import privileged + + +def _sort_interfaces(interfaces: list[str]) -> list[str]: + """Sort interfaces in a well-defined way: eth0, eth1, eth2, ... eth10.""" + + def key_func(interface): + parts = re.findall(r'(\D*)(\d*)', interface) + parts = [(string, int(number) if number else number) + for string, number in parts] + return list(itertools.chain(parts)) + + return sorted(interfaces, key=key_func) + + +def _get_interfaces() -> dict[str, list[str]]: + """Return all network interfaces by their type.""" + output = subprocess.check_output( + ['nmcli', '--terse', '--fields', 'type,device', 'device']) + interfaces = collections.defaultdict(list) + for line in output.decode().splitlines(): + type_, _, interface = line.partition(':') + interfaces[type_].append(interface) + + for type_ in interfaces: + interfaces[type_] = _sort_interfaces(interfaces[type_]) + + return interfaces + + +def _add_connection(connection_name: str, interface: str, + remaining_arguments: list[str]): + """Add an Ethernet/Wi-Fi connection of type regular or shared.""" + output = subprocess.check_output( + ['nmcli', '--terse', '--fields', 'name,device', 'con', 'show']) + lines = output.decode().splitlines() + if f'{connection_name}:{interface}' in lines: + logging.info('Connection %s already exists for device %s, not adding.', + connection_name, interface) + else: + subprocess.run([ + 'nmcli', 'con', 'add', 'con-name', connection_name, 'ifname', + interface + ] + remaining_arguments, check=True) + + +def _activate_connection(connection_name: str): + """Activate a network connection in a background process.""" + subprocess.Popen(['nohup', 'nmcli', 'con', 'up', connection_name], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + +def _configure_regular_interface(interface: str, zone: str): + """Create a connection that is not a shared connection.""" + connection_name = 'FreedomBox WAN' + properties = {'connection.autoconnect': 'TRUE', 'connection.zone': zone} + + # Create n-m connection for a regular interface + _add_connection(connection_name, interface, ['type', 'ethernet']) + _set_connection_properties(connection_name, properties) + _activate_connection(connection_name) + + logging.info('Configured interface %s for %s use as %s.', interface, zone, + connection_name) + + +def _configure_shared_interface(interface: str): + """Create a shared connection that has traffic forwarding enabled. + + Shared connection means: + - Self-assign an address and network + - Start and manage DNS server (dnsmasq) + - Start and manage DHCP server (dnsmasq) + - Register address with mDNS + - Add firewall rules for NATing from this interface + """ + connection_name = f'FreedomBox LAN {interface}' + properties = { + 'connection.autoconnect': 'TRUE', + 'connection.zone': 'internal', + 'ipv4.method': 'shared' + } + + # Create n-m connection for eth1 + _add_connection(connection_name, interface, ['type', 'ethernet']) + _set_connection_properties(connection_name, properties) + _activate_connection(connection_name) + + logging.info('Configured interface %s for shared use as %s.', interface, + connection_name) + + +def _set_connection_properties(connection_name: str, properties: dict[str, + str]): + """Configure property key/values on a connection.""" + for key, value in properties.items(): + subprocess.run(['nmcli', 'con', 'modify', connection_name, key, value], + check=True) + + +def _configure_wireless_interface(interface: str): + """Configure a wireless access point.""" + connection_name = f'FreedomBox {interface}' + ssid = f'FreedomBox{interface}' + secret = 'freedombox123' + properties = { + 'connection.autoconnect': 'TRUE', + 'connection.zone': 'internal', + 'ipv4.method': 'shared', + 'wifi.mode': 'ap', + 'wifi-sec.key-mgmt': 'wpa-psk', + 'wifi-sec.psk': secret + } + + _add_connection(connection_name, interface, ['type', 'wifi', 'ssid', ssid]) + _set_connection_properties(connection_name, properties) + _activate_connection(connection_name) + + logging.info('Configured interface %s for shared use as %s', interface, + connection_name) + + +def _multi_wired_setup(interfaces: list[str]): + """Configure all Ethernet connections on a system with many of them.""" + _configure_regular_interface(interfaces[0], 'external') + + for interface in interfaces[1:]: + _configure_shared_interface(interface) + + +def _one_wired_setup(interface: str, interfaces: dict[str, list[str]]): + """Configure an Ethernet connection on a system with only one.""" + if not len(interfaces['wifi']): + _configure_regular_interface(interface, 'internal') + else: + _configure_regular_interface(interface, 'external') + + +def _wireless_setup(interfaces: list[str]): + """Configure all wireless access points.""" + for interface in interfaces: + _configure_wireless_interface(interface) + + +@privileged +def setup(): + """Create network manager connections. + + For a user who installed using freedombox-setup Debian package, when + FreedomBox Service (Plinth) is run for the first time, don't run network + setup. This is ensured by checking for the file + /var/lib/freedombox/is-freedombox-disk-image which will not exist. + + For a user who installed using FreedomBox disk image, when FreedomBox + Service (Plinth) runs for the first time, setup process executes and + triggers the script due networks module being an essential module. + """ + if not action_utils.is_disk_image(): + logging.info( + 'Not a FreedomBox disk image. Skipping network configuration.') + return + + logging.info('Setting up network configuration...') + interfaces = _get_interfaces() + + if len(interfaces['ethernet']) == 0: + logging.info('No wired interfaces detected.') + elif len(interfaces['ethernet']) == 1: + _one_wired_setup(interfaces['ethernet'][0], interfaces) + else: + _multi_wired_setup(interfaces['ethernet']) + + _wireless_setup(interfaces['wifi']) + + logging.info('Done setting up network configuration.') diff --git a/plinth/modules/networks/tests/test_privileged.py b/plinth/modules/networks/tests/test_privileged.py new file mode 100644 index 000000000..b18de501e --- /dev/null +++ b/plinth/modules/networks/tests/test_privileged.py @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Test privileged method for networks app.""" + +from unittest.mock import patch + +from .. import privileged + + +@patch('subprocess.check_output') +def test_get_interfaces(check_output): + """Test returning list of network interfaces in sorted order.""" + check_output.return_value = '\n'.join([ + 'ethernet:ve-fbx-testing', + 'ethernet:enp39s0', + 'ethernet:enp32s1', + 'ethernet:enp4s1', + 'bridge:virbr0', + 'wifi:wlp41s0', + 'loopback:lo', + ]).encode() + + interfaces = privileged._get_interfaces() + assert interfaces == { + 'ethernet': ['enp4s1', 'enp32s1', 'enp39s0', 've-fbx-testing'], + 'bridge': ['virbr0'], + 'wifi': ['wlp41s0'], + 'loopback': ['lo'] + } diff --git a/plinth/modules/openvpn/__init__.py b/plinth/modules/openvpn/__init__.py index 4ec97d813..832723573 100644 --- a/plinth/modules/openvpn/__init__.py +++ b/plinth/modules/openvpn/__init__.py @@ -1,14 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure OpenVPN server. -""" - -import os +"""FreedomBox app to configure OpenVPN server.""" from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -18,7 +13,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ format_lazy( @@ -41,11 +36,6 @@ class OpenVPNApp(app_module.App): _version = 4 - @property - def can_be_disabled(self): - """Return whether the app can be disabled.""" - return is_setup() - def __init__(self): """Create components for the app.""" super().__init__() @@ -96,32 +86,8 @@ class OpenVPNApp(app_module.App): **manifest.backup) self.add(backup_restore) - def is_enabled(self): - """Return whether all the leader components are enabled. - - Return True when there are no leader components and OpenVPN setup - is done. - """ - return super().is_enabled() and is_setup() - def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('openvpn', ['setup']) + privileged.setup() self.enable() - - -def is_setup(): - """Return whether the service is running.""" - return actions.superuser_run('openvpn', ['is-setup']).strip() == 'true' - - -def is_using_ecc(): - """Return whether the service is using ECC.""" - if os.path.exists(SERVER_CONFIGURATION_FILE): - with open(SERVER_CONFIGURATION_FILE, 'r', - encoding='utf-8') as file_handle: - for line in file_handle: - if line.strip() == 'dh none': - return True - return False diff --git a/actions/openvpn b/plinth/modules/openvpn/privileged.py old mode 100755 new mode 100644 similarity index 67% rename from actions/openvpn rename to plinth/modules/openvpn/privileged.py index 088995bc5..e33c7c541 --- a/actions/openvpn +++ b/plinth/modules/openvpn/privileged.py @@ -1,16 +1,13 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for OpenVPN server. -""" +"""Configure OpenVPN server.""" -import argparse import os import subprocess import augeas from plinth import action_utils +from plinth.actions import privileged KEYS_DIRECTORY = '/etc/openvpn/freedombox-keys' @@ -53,26 +50,7 @@ cipher AES-256-CBC script-security 2 ''' -CLIENT_CONFIGURATION_RSA = ''' -client -remote {remote} 1194 -proto udp -proto udp6 -dev tun -nobind -remote-cert-tls server -cipher AES-256-CBC -comp-lzo -redirect-gateway -verb 3 - -{ca} - -{cert} - -{key}''' - -CLIENT_CONFIGURATION_ECC = ''' +CLIENT_CONFIGURATION = ''' client remote {remote} 1194 proto udp @@ -91,6 +69,7 @@ verb 3 {key}''' CERTIFICATE_CONFIGURATION = { + 'EASYRSA_ALGO': 'ec', 'EASYRSA_BATCH': '1', 'EASYRSA_DIGEST': 'sha512', 'KEY_CONFIG': '/usr/share/easy-rsa/openssl-easyrsa.cnf', @@ -107,59 +86,11 @@ CERTIFICATE_CONFIGURATION = { 'EASYRSA_REQ_NAME': 'FreedomBox' } -CERTIFICATE_CONFIGURATION_RSA = { - 'EASYRSA_KEY_SIZE': '4096', - **CERTIFICATE_CONFIGURATION -} - -CERTIFICATE_CONFIGURATION_ECC = { - 'EASYRSA_ALGO': 'ec', - **CERTIFICATE_CONFIGURATION -} - -COMMON_ARGS = {'env': CERTIFICATE_CONFIGURATION_ECC, 'cwd': KEYS_DIRECTORY} +COMMON_ARGS = {'env': CERTIFICATE_CONFIGURATION, 'cwd': KEYS_DIRECTORY} -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('is-setup', help='Return whether setup is completed') - subparsers.add_parser('setup', help='Setup OpenVPN server configuration') - - get_profile = subparsers.add_parser( - 'get-profile', help='Return the OpenVPN profile of a user') - get_profile.add_argument('username', help='User to get profile for') - get_profile.add_argument('remote_server', - help='The server name for the user to connect') - - subparsers.required = True - return parser.parse_args() - - -def _is_using_ecc(): - """Return whether the service is using ECC.""" - if os.path.exists(SERVER_CONFIGURATION_PATH): - with open(SERVER_CONFIGURATION_PATH, 'r', - encoding='utf-8') as file_handle: - for line in file_handle: - if line.strip() == 'dh none': - return True - return False - - -def _is_setup(): - """Return whether setup is complete.""" - return _is_non_empty_file(DH_PARAMS) or os.path.exists(EC_PARAMS_DIR) - - -def subcommand_is_setup(_): - """Print whether setup is complete.""" - print('true' if _is_setup() else 'false') - - -def subcommand_setup(_): +@privileged +def setup(): """Setup configuration, CA and certificates.""" _write_server_config() _create_certificates() @@ -236,11 +167,9 @@ def _create_certificates(): **COMMON_ARGS) -def subcommand_get_profile(arguments): +@privileged +def get_profile(username: str, remote_server: str) -> str: """Return the profile for a user.""" - username = arguments.username - remote_server = arguments.remote_server - if username == 'ca' or username == 'server': raise Exception('Invalid username') @@ -253,27 +182,20 @@ def subcommand_get_profile(arguments): subprocess.check_call([ '/usr/share/easy-rsa/easyrsa', 'build-client-full', username, 'nopass' - ], env=CERTIFICATE_CONFIGURATION_ECC if _is_using_ecc() else - CERTIFICATE_CONFIGURATION_RSA, - cwd=KEYS_DIRECTORY) + ], env=CERTIFICATE_CONFIGURATION, cwd=KEYS_DIRECTORY) user_certificate_string = _read_file(user_certificate) user_key_string = _read_file(user_key) ca_string = _read_file(CA_CERTIFICATE_PATH) - client_configuration = CLIENT_CONFIGURATION_ECC if _is_using_ecc( - ) else CLIENT_CONFIGURATION_RSA - - profile = client_configuration.format(ca=ca_string, - cert=user_certificate_string, - key=user_key_string, - remote=remote_server) - - print(profile) + return CLIENT_CONFIGURATION.format(ca=ca_string, + cert=user_certificate_string, + key=user_key_string, + remote=remote_server) def set_unique_subject(value): - """ Sets the unique_subject value to a particular value""" + """Set the unique_subject value to a particular value.""" aug = load_augeas() aug.set('/files' + ATTR_FILE + '/unique_subject', value) aug.save() @@ -300,16 +222,3 @@ def load_augeas(): aug.set('/augeas/load/Simplevars/incl[last() + 1]', ATTR_FILE) aug.load() return aug - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/openvpn/templates/migrate_to_ecc.html b/plinth/modules/openvpn/templates/migrate_to_ecc.html deleted file mode 100644 index 8f22afab1..000000000 --- a/plinth/modules/openvpn/templates/migrate_to_ecc.html +++ /dev/null @@ -1,39 +0,0 @@ -{% comment %} -# SPDX-License-Identifier: AGPL-3.0-or-later -{% endcomment %} - -{% load i18n %} - -

{% trans "Migrate to ECC" %}

- -

- {% blocktrans trimmed %} - Your OpenVPN installation is currently using RSA. Switching to the - modern Elliptic Curve Cryptography improves speed of establishing a - connection and security. This operation is irreversible. It should only take - a few minutes on most single board computers. - {% endblocktrans %} -

- -

- {% blocktrans trimmed %} - All new installations of OpenVPN on {{ box_name }} will - use ECC by default. We recommend migrating as soon as possible. - {% endblocktrans %} -

- -

- {% blocktrans trimmed %} - Warning: Existing client profiles will be invalidated by this operation. All - OpenVPN users on {{ box_name }} must download their new profiles. OpenVPN - clients compatible with ECC should be used to connect to this server. - {% endblocktrans %} -

- -
- {% csrf_token %} - - -
diff --git a/plinth/modules/openvpn/templates/openvpn.html b/plinth/modules/openvpn/templates/openvpn.html index 62a42c3e8..6c2d8a4cb 100644 --- a/plinth/modules/openvpn/templates/openvpn.html +++ b/plinth/modules/openvpn/templates/openvpn.html @@ -7,49 +7,31 @@ {% load i18n %} {% load static %} -{% block status %} - - {% if status.is_setup %} - {{ block.super }} - {% endif %} - -{% endblock %} - {% block configuration %} - {% if status.is_setup %} +

{% trans "Profile" %}

-

{% trans "Profile" %}

+

+ {% blocktrans trimmed %} + To connect to {{ box_name }}'s VPN, you need to download a profile and + feed it to an OpenVPN client on your mobile or desktop machine. OpenVPN + Clients are available for most platforms. Click "Learn more..." above for + recommended clients and instructions on how to configure them. + {% endblocktrans %} +

-

- {% blocktrans trimmed %} - To connect to {{ box_name }}'s VPN, you need to download a - profile and feed it to an OpenVPN client on your mobile or - desktop machine. OpenVPN Clients are available for most - platforms. Click "Learn more..." above for recommended clients - and instructions on how to configure them. - {% endblocktrans %} -

+

+ {% blocktrans trimmed %} + Profile is specific to each user of {{ box_name }}. Keep it a secret. + {% endblocktrans %} +

-

- {% blocktrans trimmed %} - Profile is specific to each user of {{ box_name }}. Keep it a - secret. - {% endblocktrans %} -

+
+ {% csrf_token %} - - {% csrf_token %} - - -
- - {% if not using_ecc %} - {% include "migrate_to_ecc.html" %} - {% endif %} - - {% endif %} + + {% endblock %} diff --git a/plinth/modules/openvpn/tests/test_configuration.py b/plinth/modules/openvpn/tests/test_configuration.py deleted file mode 100644 index 35dd75d1a..000000000 --- a/plinth/modules/openvpn/tests/test_configuration.py +++ /dev/null @@ -1,67 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -""" -Test module for OpenVPN configuration. -""" - -import os -from unittest.mock import patch - -import pytest - -from plinth.modules import openvpn - -actions_name = 'openvpn' - - -@pytest.fixture(name='keys_directory') -def fixture_keys_directory(tmp_path): - return tmp_path - - -@pytest.fixture(autouse=True) -def fixture_set_keys_directory(actions_module, keys_directory): - """Set the keys directory in the actions module.""" - actions_module.DH_PARAMS = f'{keys_directory}/pki/dh.pem' - actions_module.EC_PARAMS_DIR = f'{keys_directory}/pki/ecparams' - - -@pytest.fixture(name='conf_file') -def fixture_conf_file(tmp_path): - """Fixture that returns an empty configuration file.""" - return str(tmp_path / 'freedombox.conf') - - -def test_identify_rsa_configuration(conf_file): - """Identify RSA configuration based on configuration file.""" - with patch('plinth.modules.openvpn.SERVER_CONFIGURATION_FILE', conf_file): - with open(conf_file, 'w', encoding='utf-8') as file_handle: - file_handle.write('dh /etc/openvpn/freedombox-keys/pki/dh.pem') - assert not openvpn.is_using_ecc() - - -def test_identify_ecc_configuration(conf_file): - """Identify ECC configuration based on configuration file.""" - with patch('plinth.modules.openvpn.SERVER_CONFIGURATION_FILE', conf_file): - with open(conf_file, 'w', encoding='utf-8') as file_handle: - file_handle.write('dh none') - assert openvpn.is_using_ecc() - - -def test_is_setup_with_rsa(keys_directory, call_action): - """is_setup should work with RSA configuration.""" - with patch('plinth.actions.superuser_run', call_action): - (keys_directory / 'pki').mkdir() - dh_params_file = keys_directory / 'pki' / 'dh.pem' - dh_params_file.write_text('some content') - assert openvpn.is_setup() - os.remove(dh_params_file) - - -def test_is_setup_with_ecc(keys_directory, call_action): - """is_setup should work with RSA configuration.""" - with patch('plinth.actions.superuser_run', call_action): - (keys_directory / 'pki' / 'ecparams').mkdir(parents=True) - ec_params_file = keys_directory / 'pki' / 'ecparams' / 'somecurve.pem' - ec_params_file.write_text('some content') - assert openvpn.is_setup() - os.remove(ec_params_file) diff --git a/plinth/modules/openvpn/urls.py b/plinth/modules/openvpn/urls.py index 77b24d3e1..e9382644b 100644 --- a/plinth/modules/openvpn/urls.py +++ b/plinth/modules/openvpn/urls.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -URLs for the OpenVPN module. -""" +"""URLs for the OpenVPN module.""" from django.urls import re_path @@ -11,8 +9,6 @@ from . import views urlpatterns = [ re_path(r'^apps/openvpn/$', views.OpenVPNAppView.as_view(), name='index'), - re_path(r'^apps/openvpn/setup/$', views.setup, name='setup'), - re_path(r'^apps/openvpn/ecc/$', views.ecc, name='ecc'), re_path(r'^apps/openvpn/profile/$', user_group_view(views.profile, 'vpn'), name='profile'), ] diff --git a/plinth/modules/openvpn/views.py b/plinth/modules/openvpn/views.py index 903093bd6..3dad16fc2 100644 --- a/plinth/modules/openvpn/views.py +++ b/plinth/modules/openvpn/views.py @@ -1,47 +1,24 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring OpenVPN server. -""" +"""FreedomBox app for configuring OpenVPN server.""" import logging from django.http import HttpResponse -from django.shortcuts import redirect -from django.views.decorators.http import require_POST -from plinth import actions -from plinth import app as app_module -from plinth.modules import config, openvpn +from plinth.modules import config from plinth.views import AppView +from . import privileged + logger = logging.getLogger(__name__) class OpenVPNAppView(AppView): """Show OpenVPN app main page.""" + app_id = 'openvpn' template_name = 'openvpn.html' - def get_context_data(self, *args, **kwargs): - """Add additional context data for template.""" - context = super().get_context_data(*args, **kwargs) - context['status'] = { - 'is_setup': openvpn.is_setup(), - } - context['using_ecc'] = openvpn.is_using_ecc() - return context - - -@require_POST -def setup(_): - """Start the setup process.""" - if not openvpn.is_setup(): - actions.superuser_run('openvpn', ['setup'], run_in_background=True) - - app_module.App.get('openvpn').enable() - - return redirect('openvpn:index') - def profile(request): """Provide the user's profile for download.""" @@ -51,20 +28,10 @@ def profile(request): if not config.get_domainname(): domainname = config.get_hostname() - profile_string = actions.superuser_run( - 'openvpn', ['get-profile', username, domainname]) - + profile_string = privileged.get_profile(username, domainname) response = HttpResponse(profile_string, content_type='application/x-openvpn-profile') response['Content-Disposition'] = \ 'attachment; filename={username}.ovpn'.format(username=username) return response - - -@require_POST -def ecc(_): - """Migrate from RSA to ECC.""" - if openvpn.is_setup(): - actions.superuser_run('openvpn', ['setup'], run_in_background=True) - return redirect('openvpn:index') diff --git a/plinth/modules/pagekite/__init__.py b/plinth/modules/pagekite/__init__.py index d959a0286..c9df15ec2 100644 --- a/plinth/modules/pagekite/__init__.py +++ b/plinth/modules/pagekite/__init__.py @@ -1,17 +1,15 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure PageKite. -""" +"""FreedomBox app to configure PageKite.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu from plinth.daemon import Daemon from plinth.modules.backups.components import BackupRestore from plinth.modules.names.components import DomainType from plinth.package import Packages +from plinth.privileged import service as service_privileged from plinth.utils import format_lazy from . import manifest, utils @@ -106,5 +104,4 @@ class PagekiteApp(app_module.App): self.enable() if old_version == 1: - actions.superuser_run('service', - ['try-restart', PagekiteApp.DAEMON]) + service_privileged.try_restart(PagekiteApp.DAEMON) diff --git a/plinth/modules/pagekite/forms.py b/plinth/modules/pagekite/forms.py index a05c8a6b8..0ca0539a1 100644 --- a/plinth/modules/pagekite/forms.py +++ b/plinth/modules/pagekite/forms.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later +"""Forms for configuring Pagekite.""" import copy -import json from django import forms from django.contrib import messages @@ -9,16 +9,14 @@ from django.core import validators from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy -from plinth.errors import ActionError - -from . import utils +from . import privileged, utils class TrimmedCharField(forms.CharField): - """Trim the contents of a CharField""" + """Trim the contents of a CharField.""" def clean(self, value): - """Clean and validate the field value""" + """Clean and validate the field value.""" if value: value = value.strip() @@ -26,7 +24,7 @@ class TrimmedCharField(forms.CharField): class ConfigurationForm(forms.Form): - """Configure PageKite credentials and frontend""" + """Configure PageKite credentials and frontend.""" server_domain = forms.CharField( label=gettext_lazy('Server domain'), required=False, @@ -72,9 +70,7 @@ class ConfigurationForm(forms.Form): if old != new: frontend = f"{new['server_domain']}:{new['server_port']}" - utils.run([ - 'set-config', '--kite-name', kite_name, '--frontend', frontend - ], input=new['kite_secret'].encode()) + privileged.set_config(frontend, kite_name, new['kite_secret']) messages.success(request, _('Configuration updated')) # Update kite name registered with Name Services module. @@ -82,7 +78,8 @@ class ConfigurationForm(forms.Form): class BaseCustomServiceForm(forms.Form): - """Basic form functionality to handle a custom service""" + """Basic form functionality to handle a custom service.""" + choices = [('http', 'http'), ('https', 'https'), ('raw', 'raw')] protocol = forms.ChoiceField(choices=choices, label=gettext_lazy('protocol')) @@ -96,7 +93,7 @@ class BaseCustomServiceForm(forms.Form): required=False) def convert_formdata_to_service(self, formdata): - """Add information to make a service out of the form data""" + """Add information to make a service out of the form data.""" # convert integers to str (to compare values with DEFAULT_SERVICES) for field in ('frontend_port', 'backend_port'): formdata[field] = str(formdata[field]) @@ -126,15 +123,15 @@ class DeleteCustomServiceForm(BaseCustomServiceForm): def delete(self, request): service = self.convert_formdata_to_service(self.cleaned_data) - utils.run(['remove-service', '--service', json.dumps(service)]) + privileged.remove_service(service) messages.success(request, _('Deleted custom service')) class AddCustomServiceForm(BaseCustomServiceForm): - """Adds the save() method and validation to not add predefined services""" + """Adds the save() method and validation to not add predefined services.""" def matches_predefined_service(self, formdata): - """Returns whether the user input matches a predefined service""" + """Return whether the user input matches a predefined service.""" service = self.convert_formdata_to_service(formdata) match_found = False for predefined_service_obj in utils.PREDEFINED_SERVICES.values(): @@ -168,9 +165,9 @@ class AddCustomServiceForm(BaseCustomServiceForm): def save(self, request): service = self.convert_formdata_to_service(self.cleaned_data) try: - utils.run(['add-service', '--service', json.dumps(service)]) + privileged.add_service(service) messages.success(request, _('Added custom service')) - except ActionError as exception: + except Exception as exception: if "already exists" in str(exception): messages.error(request, _('This service already exists')) else: diff --git a/actions/pagekite b/plinth/modules/pagekite/privileged.py old mode 100755 new mode 100644 similarity index 67% rename from actions/pagekite rename to plinth/modules/pagekite/privileged.py index b57ad2cd1..f9b5eec69 --- a/actions/pagekite +++ b/plinth/modules/pagekite/privileged.py @@ -1,21 +1,15 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for PageKite interface. -""" +"""Configure PageKite.""" -import argparse -import json import os -import sys +from typing import Union import augeas from plinth import action_utils +from plinth.actions import privileged from plinth.modules.pagekite import utils -aug = None - PATHS = { 'service_on': os.path.join(utils.CONF_PATH, '*', 'service_on', '*'), @@ -32,35 +26,10 @@ PATHS = { } -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - # Configuration - subparsers.add_parser('get-config', help='Return current configuration') - set_config = subparsers.add_parser( - 'set-config', - help='Configure kite name, its secret and frontend. Secret is read ' - 'from stdin.') - set_config.add_argument('--kite-name', - help='Name of the kite (eg: mybox.pagekite.me)') - set_config.add_argument('--frontend', help='Frontend url') - - # Add/remove pagekite services (service_on entries) - add_service = subparsers.add_parser('add-service', - help='Add a pagekite service') - add_service.add_argument('--service', help='json service dictionary') - remove_service = subparsers.add_parser('remove-service', - help='Remove a pagekite service') - remove_service.add_argument('--service', help='json service dictionary') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_get_config(_): - """Print the current configuration as JSON dictionary.""" +@privileged +def get_config() -> dict[str, object]: + """Return the current configuration as JSON dictionary.""" + aug = _augeas_load() if aug.match(PATHS['abort_not_configured']): aug.remove(PATHS['abort_not_configured']) aug.save() @@ -70,9 +39,9 @@ def subcommand_get_config(_): else: frontend = aug.get(PATHS['frontend']) or '' - frontend = frontend.split(':') - server_domain = frontend[0] - server_port = frontend[1] if len(frontend) >= 2 else '80' + frontend_parts = frontend.split(':') + server_domain = frontend_parts[0] + server_port = frontend_parts[1] if len(frontend_parts) >= 2 else '80' status = { 'kite_name': aug.get(PATHS['kitename']), @@ -113,30 +82,32 @@ def subcommand_get_config(_): service['url'] = url - print(json.dumps(status)) + return status -def subcommand_set_config(arguments): +@privileged +def set_config(frontend: str, kite_name: str, kite_secret: str): """Set pagekite kite name, secret and frontend URL.""" + aug = _augeas_load() aug.remove(PATHS['abort_not_configured']) - aug.set(PATHS['kitename'], arguments.kite_name) - aug.set(PATHS['kitesecret'], sys.stdin.read()) + aug.set(PATHS['kitename'], kite_name) + aug.set(PATHS['kitesecret'], kite_secret) - frontend_domain = arguments.frontend.split(':')[0] + frontend_domain = frontend.split(':')[0] if frontend_domain in ('pagekite.net', 'defaults', 'default'): aug.set(PATHS['defaults'], '') aug.remove(PATHS['frontend']) else: aug.remove(PATHS['defaults']) - aug.set(PATHS['frontend'], arguments.frontend) + aug.set(PATHS['frontend'], frontend) aug.save() for service_name in utils.PREDEFINED_SERVICES.keys(): service = utils.PREDEFINED_SERVICES[service_name]['params'] try: - _add_service(service) + _add_service(aug, service) except RuntimeError: pass @@ -146,10 +117,12 @@ def subcommand_set_config(arguments): action_utils.service_restart('pagekite') -def subcommand_remove_service(arguments): - """Searches and removes the service(s) that match all given parameters""" - service = utils.load_service(arguments.service) - paths = _get_existing_service_paths(service) +@privileged +def remove_service(service: dict[str, Union[str, bool]]): + """Search and remove the service(s) that match all given parameters.""" + aug = _augeas_load() + service = utils.load_service(service) + paths = _get_existing_service_paths(aug, service) # TODO: theoretically, everything to do here is: # [aug.remove(path) for path in paths] # but augeas won't let you save the changed files and doesn't say why @@ -172,8 +145,8 @@ def subcommand_remove_service(arguments): action_utils.service_restart('pagekite') -def _get_existing_service_paths(service, keys=None): - """Return paths of existing services that match the given service params""" +def _get_existing_service_paths(aug, service, keys=None): + """Return paths of existing services that match the given service.""" # construct an augeas query path with patterns like: # */service_on/*[protocol='http'] path = PATHS['service_on'] @@ -182,13 +155,13 @@ def _get_existing_service_paths(service, keys=None): return aug.match(path) -def _add_service(service): +def _add_service(aug, service): """Add a new service into configuration.""" - if _get_existing_service_paths(service, ['protocol', 'kitename']): + if _get_existing_service_paths(aug, service, ['protocol', 'kitename']): msg = "Service with the parameters %s already exists" raise RuntimeError(msg % service) - root = _get_new_service_path(service['protocol']) + root = _get_new_service_path(aug, service['protocol']) # TODO: after adding a service, augeas fails writing the config; # so add the service_on entry manually instead path = _convert_augeas_path_to_filepath(root) @@ -197,16 +170,18 @@ def _add_service(service): servicefile.write(line) -def subcommand_add_service(arguments): - """Add one service""" - service = utils.load_service(arguments.service) - _add_service(service) +@privileged +def add_service(service: dict[str, Union[str, bool]]): + """Add one service.""" + aug = _augeas_load() + service = utils.load_service(service) + _add_service(aug, service) action_utils.service_try_restart('pagekite') def _convert_augeas_path_to_filepath(augpath, prefix='/files', suffix='service_on'): - """Convert an augeas service_on path to the actual file path""" + """Convert an augeas service_on path to the actual file path.""" if augpath.startswith(prefix): augpath = augpath.replace(prefix, "", 1) @@ -216,35 +191,21 @@ def _convert_augeas_path_to_filepath(augpath, prefix='/files', return augpath.rstrip('/') -def _get_new_service_path(protocol): - """Get the augeas path of a new service for a protocol +def _get_new_service_path(aug, protocol): + """Get the augeas path of a new service for a protocol. - This takes care of existing services using a /service_on/*/ query""" + This takes care of existing services using a /service_on/*/ query + """ root = utils.get_augeas_servicefile_path(protocol) new_index = len(aug.match(root + '/*')) + 1 return os.path.join(root, str(new_index)) -def augeas_load(): +def _augeas_load(): """Initialize Augeas.""" - global aug aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) aug.set('/augeas/load/Pagekite/lens', 'Pagekite.lns') aug.set('/augeas/load/Pagekite/incl[last() + 1]', '/etc/pagekite.d/*.rc') aug.load() - - -def main(): - """Parse arguments and perform all duties""" - augeas_load() - - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == "__main__": - main() + return aug diff --git a/plinth/modules/pagekite/utils.py b/plinth/modules/pagekite/utils.py index 8b00cf7b6..77d5058e1 100644 --- a/plinth/modules/pagekite/utils.py +++ b/plinth/modules/pagekite/utils.py @@ -1,12 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later +"""Utilities for configuring Pagekite.""" -import json import logging import os from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth.signals import domain_added, domain_removed @@ -80,21 +79,6 @@ PREDEFINED_SERVICES = { } -def get_config(): - """Return the current PageKite configuration.""" - return json.loads(run(['get-config'])) - - -def run(arguments, superuser=True, input=None): - """Run a given command and raise exception if there was an error""" - command = 'pagekite' - - if superuser: - return actions.superuser_run(command, arguments, input=input) - else: - return actions.run(command, arguments, input=input) - - def convert_service_to_string(service): """ Convert service dict into a ":"-separated parameter string @@ -110,15 +94,14 @@ def convert_service_to_string(service): return service_string -def load_service(json_service): - """ create a service out of json command-line argument +def load_service(service): + """Create a service out of json command-line argument. 1) parse json 2) only use the parameters that we need (SERVICE_PARAMS) 3) convert unicode to strings """ - service = json.loads(json_service) - return dict((str(key), str(service[key])) for key in SERVICE_PARAMS) + return {str(key): str(service[key]) for key in SERVICE_PARAMS} def get_augeas_servicefile_path(protocol): @@ -176,7 +159,8 @@ def update_names_module(is_enabled=None): if is_enabled is None and not app_module.App.get('pagekite').is_enabled(): return - config = get_config() + from . import privileged + config = privileged.get_config() enabled_services = [ service for service, value in config['predefined_services'].items() if value @@ -186,8 +170,3 @@ def update_names_module(is_enabled=None): domain_type='domain-type-pagekite', name=config['kite_name'], services=enabled_services) - - -if __name__ == "__main__": - import doctest - doctest.testmod() diff --git a/plinth/modules/pagekite/views.py b/plinth/modules/pagekite/views.py index b5307b9cd..c5dde2e59 100644 --- a/plinth/modules/pagekite/views.py +++ b/plinth/modules/pagekite/views.py @@ -8,7 +8,7 @@ from django.views.generic.edit import FormView from plinth.views import AppView -from . import utils +from . import privileged from .forms import (AddCustomServiceForm, ConfigurationForm, DeleteCustomServiceForm) @@ -50,7 +50,7 @@ class ConfigurationView(AppView): def __init__(self, *args, **kwargs): """Load and store the current configuration.""" super().__init__(*args, **kwargs) - self.config = utils.get_config() + self.config = privileged.get_config() self.initial = self.config def get_context_data(self, *args, **kwargs): diff --git a/plinth/modules/power/privileged.py b/plinth/modules/power/privileged.py new file mode 100644 index 000000000..06e22967c --- /dev/null +++ b/plinth/modules/power/privileged.py @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Shutdown/restart the system.""" + +import subprocess + +from plinth.actions import privileged + + +@privileged +def restart(): + """Restart the system.""" + subprocess.call('reboot') + + +@privileged +def shutdown(): + """Shut down the system.""" + subprocess.call(['shutdown', 'now']) diff --git a/plinth/modules/power/views.py b/plinth/modules/power/views.py index d88d10eea..c4198f09e 100644 --- a/plinth/modules/power/views.py +++ b/plinth/modules/power/views.py @@ -1,18 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for power module. -""" +"""FreedomBox app for power controls.""" from django.forms import Form from django.shortcuts import redirect from django.template.response import TemplateResponse from django.urls import reverse -from plinth import actions from plinth import app as app_module from plinth import package from plinth.views import AppView +from . import privileged + class PowerAppView(AppView): """Show power app main page.""" @@ -23,7 +22,8 @@ class PowerAppView(AppView): def get_context_data(self, *args, **kwargs): """Add additional context data for template.""" context = super().get_context_data(*args, **kwargs) - context['pkg_manager_is_busy'] = package.is_package_manager_busy() + is_busy = package.is_package_manager_busy() + context['pkg_manager_is_busy'] = is_busy return context @@ -32,17 +32,18 @@ def restart(request): form = None if request.method == 'POST': - actions.superuser_run('power', ['restart'], run_in_background=True) + privileged.restart(_run_in_background=True) return redirect(reverse('apps')) app = app_module.App.get('power') form = Form(prefix='power') + is_busy = package.is_package_manager_busy() return TemplateResponse( request, 'power_restart.html', { 'title': app.info.name, 'form': form, 'manual_page': app.info.manual_page, - 'pkg_manager_is_busy': package.is_package_manager_busy() + 'pkg_manager_is_busy': is_busy }) @@ -51,15 +52,16 @@ def shutdown(request): form = None if request.method == 'POST': - actions.superuser_run('power', ['shutdown'], run_in_background=True) + privileged.shutdown(_run_in_background=True) return redirect(reverse('apps')) app = app_module.App.get('power') form = Form(prefix='power') + is_busy = package.is_package_manager_busy() return TemplateResponse( request, 'power_shutdown.html', { 'title': app.info.name, 'form': form, 'manual_page': app.info.manual_page, - 'pkg_manager_is_busy': package.is_package_manager_busy() + 'pkg_manager_is_busy': is_busy }) diff --git a/plinth/modules/privacy/__init__.py b/plinth/modules/privacy/__init__.py new file mode 100644 index 000000000..e0bdfacd8 --- /dev/null +++ b/plinth/modules/privacy/__init__.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""FreedomBox app to the Privacy app.""" + +import augeas +from django.utils.translation import gettext_lazy as _ +from django.utils.translation import gettext_noop + +from plinth import app as app_module +from plinth import menu +from plinth.modules.backups.components import BackupRestore +from plinth.package import Packages + +from . import manifest, privileged + +_description = [_('Manage system-wide privacy settings.')] + + +class PrivacyApp(app_module.App): + """FreedomBox app for Privacy.""" + + app_id = 'privacy' + + _version = 1 + + can_be_disabled = False + + def __init__(self): + """Create components for the app.""" + super().__init__() + + info = app_module.Info(app_id=self.app_id, version=self._version, + is_essential=True, name=_('Privacy'), + icon='fa-eye-slash', description=_description, + manual_page=None) + self.add(info) + + menu_item = menu.Menu('menu-privacy', info.name, + info.short_description, info.icon, + 'privacy:index', parent_url_name='system') + self.add(menu_item) + + packages = Packages('packages-privacy', ['popularity-contest', 'gpg']) + self.add(packages) + + backup_restore = BackupRestore('backup-restore-privacy', + **manifest.backup) + self.add(backup_restore) + + def setup(self, old_version): + """Install and configure the app.""" + super().setup(old_version) + privileged.setup() + if old_version == 0: + privileged.set_configuration(enable_popcon=True) + _show_privacy_notification() + + +def _show_privacy_notification(): + """Show a notification asking user to review privacy settings.""" + from plinth.notification import Notification + message = gettext_noop( + 'Please update privacy settings to match your preferences.') + data = { + 'app_name': 'translate:' + gettext_noop('Privacy'), + 'app_icon': 'fa-eye-slash' + } + title = gettext_noop('Review privacy setting') + actions_ = [{ + 'type': 'link', + 'class': 'primary', + 'text': gettext_noop('Go to {app_name}'), + 'url': 'privacy:index' + }, { + 'type': 'dismiss' + }] + Notification.update_or_create(id='privacy-review', app_id='privacy', + severity='info', title=title, + message=message, actions=actions_, data=data, + group='admin') diff --git a/plinth/modules/privacy/data/etc/dpkg/origins/freedombox b/plinth/modules/privacy/data/etc/dpkg/origins/freedombox new file mode 100644 index 000000000..9f2810477 --- /dev/null +++ b/plinth/modules/privacy/data/etc/dpkg/origins/freedombox @@ -0,0 +1,4 @@ +Vendor: FreedomBox +Vendor-URL: https://freedombox.org/ +Bugs: https://salsa.debian.org/freedombox-team/freedombox/-/issues/new +Parent: Debian diff --git a/plinth/modules/privacy/data/etc/plinth/modules-enabled/privacy b/plinth/modules/privacy/data/etc/plinth/modules-enabled/privacy new file mode 100644 index 000000000..a782d038c --- /dev/null +++ b/plinth/modules/privacy/data/etc/plinth/modules-enabled/privacy @@ -0,0 +1 @@ +plinth.modules.privacy diff --git a/plinth/modules/privacy/forms.py b/plinth/modules/privacy/forms.py new file mode 100644 index 000000000..c824b63a5 --- /dev/null +++ b/plinth/modules/privacy/forms.py @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""FreedomBox privacy app.""" + +from django import forms +from django.utils.translation import gettext_lazy as _ + +from plinth import cfg +from plinth.utils import format_lazy + + +class PrivacyForm(forms.Form): + """Privacy configuration form.""" + + enable_popcon = forms.BooleanField( + label=_('Periodically submit a list of apps used (suggested)'), + required=False, help_text=format_lazy( + _('Help Debian/{box_name} developers by participating in the ' + 'Popularity Contest package survey program. When enabled, a ' + 'list of apps used on this system will be anonymously submitted ' + 'to Debian every week. Statistics for the data collected are ' + 'publicly available at popcon.debian.org. Submission happens over ' + 'the Tor network for additional anonymity if Tor app is enabled.' + ), box_name=_(cfg.box_name))) diff --git a/plinth/modules/privacy/manifest.py b/plinth/modules/privacy/manifest.py new file mode 100644 index 000000000..a10591d1c --- /dev/null +++ b/plinth/modules/privacy/manifest.py @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Application manifest for privacy app.""" + +from . import privileged + +backup = {'config': {'files': [str(privileged.CONFIG_FILE)]}} diff --git a/plinth/modules/privacy/privileged.py b/plinth/modules/privacy/privileged.py new file mode 100644 index 000000000..04faff907 --- /dev/null +++ b/plinth/modules/privacy/privileged.py @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure Privacy App.""" + +import pathlib +from typing import Optional + +import augeas + +from plinth.actions import privileged + +CONFIG_FILE = pathlib.Path('/etc/popularity-contest.d/freedombox.conf') + + +@privileged +def setup(): + """Create initial popcon configuration.""" + CONFIG_FILE.parent.mkdir(exist_ok=True) + CONFIG_FILE.touch() + + aug = _load_augeas() + aug.set('ENCRYPT', 'yes') + aug.save() + + # Set the vendor to 'FreedomBox' with 'Debian' as parent + default_link = pathlib.Path('/etc/dpkg/origins/default') + debian_link = pathlib.Path('/etc/dpkg/origins/debian') + if default_link.is_symlink() and default_link.resolve() == debian_link: + default_link.unlink() + default_link.symlink_to('freedombox') + + +@privileged +def set_configuration(enable_popcon: Optional[bool] = None): + """Update popcon configuration.""" + aug = _load_augeas() + if enable_popcon: + aug.set('PARTICIPATE', 'yes') + else: + aug.set('PARTICIPATE', 'no') + + aug.save() + + +def get_configuration() -> dict[str, bool]: + """Return if popcon participation is enabled.""" + aug = _load_augeas() + value = aug.get('PARTICIPATE') + return {'enable_popcon': (value == 'yes')} + + +def _load_augeas(): + """Initialize Augeas.""" + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) + aug.transform('Shellvars', str(CONFIG_FILE)) + aug.set('/augeas/context', '/files' + str(CONFIG_FILE)) + aug.load() + return aug diff --git a/plinth/modules/privacy/tests/__init__.py b/plinth/modules/privacy/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/plinth/modules/privacy/tests/test_functional.py b/plinth/modules/privacy/tests/test_functional.py new file mode 100644 index 000000000..21b0ee1f4 --- /dev/null +++ b/plinth/modules/privacy/tests/test_functional.py @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Functional, browser based tests for privacy app.""" + +import pytest + +from plinth.tests import functional + +pytestmark = [pytest.mark.system, pytest.mark.privacy] + + +class TestPrivacyApp(functional.BaseAppTests): + """Tests for privacy app.""" + + app_name = 'privacy' + has_service = False + has_web = False + disable_after_tests = False + + @pytest.fixture(autouse=True) + def fixture_background(self, session_browser): + """Login, install, and enable the app.""" + functional.login(session_browser) + functional.nav_to_module(session_browser, self.app_name) + yield + + def test_enable_disable(self, session_browser): + """Skip test for enabling and disabling the app.""" + pytest.skip('Can not be disabled') + + @pytest.mark.backups + def test_enable_disable_popcon(self, session_browser): + """Test that popcon can be enable/disabled.""" + functional.change_checkbox_status(session_browser, self.app_name, + 'id_enable_popcon', 'disabled') + functional.change_checkbox_status(session_browser, self.app_name, + 'id_enable_popcon', 'enabled') + assert session_browser.find_by_id('id_enable_popcon').checked + functional.change_checkbox_status(session_browser, self.app_name, + 'id_enable_popcon', 'disabled') + assert not session_browser.find_by_id('id_enable_popcon').checked + + @pytest.mark.backups + def test_backup_restore(self, session_browser): + """Test that backup and restore operations work on the app.""" + functional.change_checkbox_status(session_browser, self.app_name, + 'id_enable_popcon', 'disabled') + functional.backup_create(session_browser, self.app_name, + 'test_' + self.app_name) + functional.nav_to_module(session_browser, self.app_name) + functional.change_checkbox_status(session_browser, self.app_name, + 'id_enable_popcon', 'enabled') + functional.backup_restore(session_browser, self.app_name, + 'test_' + self.app_name) + functional.nav_to_module(session_browser, self.app_name) + assert not session_browser.find_by_id('id_enable_popcon').checked + + def test_uninstall(self, session_browser): + """Skip test for uninstall.""" + pytest.skip('Essential app') diff --git a/plinth/modules/privacy/urls.py b/plinth/modules/privacy/urls.py new file mode 100644 index 000000000..d0c28ee5c --- /dev/null +++ b/plinth/modules/privacy/urls.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""URLs for the Privacy module.""" + +from django.urls import re_path + +from .views import PrivacyAppView + +urlpatterns = [ + re_path(r'^sys/privacy/$', PrivacyAppView.as_view(), name='index'), +] diff --git a/plinth/modules/privacy/views.py b/plinth/modules/privacy/views.py new file mode 100644 index 000000000..a60e091e1 --- /dev/null +++ b/plinth/modules/privacy/views.py @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Views for privacy app.""" + +from django.contrib import messages +from django.utils.translation import gettext as _ + +from plinth.modules.privacy.forms import PrivacyForm +from plinth.views import AppView + +from . import privileged + + +class PrivacyAppView(AppView): + """Serve configuration page.""" + + app_id = 'privacy' + form_class = PrivacyForm + + def get_initial(self): + """Return the values to fill in the form.""" + initial = super().get_initial() + initial.update(privileged.get_configuration()) + return initial + + def form_valid(self, form): + """Change the configurations of Minetest service.""" + new_config = form.cleaned_data + old_config = form.initial + + changes = {} + if old_config['enable_popcon'] != new_config['enable_popcon']: + changes['enable_popcon'] = new_config['enable_popcon'] + + if changes: + privileged.set_configuration(**changes) + messages.success(self.request, _('Configuration updated')) + + return super().form_valid(form) diff --git a/plinth/modules/quassel/__init__.py b/plinth/modules/quassel/__init__.py index 0405e9cb9..284e67642 100644 --- a/plinth/modules/quassel/__init__.py +++ b/plinth/modules/quassel/__init__.py @@ -1,14 +1,11 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for Quassel. -""" +"""FreedomBox app for Quassel.""" import pathlib from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -20,7 +17,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ format_lazy( @@ -108,7 +105,7 @@ class QuasselApp(app_module.App): def set_domain(domain): """Set the TLS domain by writing a file to data directory.""" if domain: - actions.superuser_run('quassel', ['set-domain', domain]) + privileged.set_domain(domain) def get_domain(): diff --git a/plinth/modules/quassel/privileged.py b/plinth/modules/quassel/privileged.py new file mode 100644 index 000000000..bab66e9dd --- /dev/null +++ b/plinth/modules/quassel/privileged.py @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure Quassel.""" + +import pathlib + +from plinth.actions import privileged + + +@privileged +def set_domain(domain_name: str): + """Write a file containing domain name.""" + domain_file = pathlib.Path('/var/lib/quassel/domain-freedombox') + domain_file.write_text(domain_name, encoding='utf-8') diff --git a/plinth/modules/radicale/__init__.py b/plinth/modules/radicale/__init__.py index 118f60164..372addf5c 100644 --- a/plinth/modules/radicale/__init__.py +++ b/plinth/modules/radicale/__init__.py @@ -8,7 +8,6 @@ import logging import augeas from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.modules.apache.components import Uwsgi, Webserver @@ -18,7 +17,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages, install from plinth.utils import Version, format_lazy -from . import manifest +from . import manifest, privileged _description = [ format_lazy( @@ -93,7 +92,7 @@ class RadicaleApp(app_module.App): def enable(self): """Fix missing directories before enabling radicale.""" - actions.superuser_run('radicale', ['fix-paths']) + privileged.fix_paths() super().enable() def setup(self, old_version): @@ -113,8 +112,7 @@ class RadicaleApp(app_module.App): rights = get_rights_value() install(['radicale'], force_configuration='new') - actions.superuser_run('radicale', - ['configure', '--rights_type', rights]) + privileged.configure(rights) return True diff --git a/plinth/modules/radicale/privileged.py b/plinth/modules/radicale/privileged.py new file mode 100644 index 000000000..7c950dcf0 --- /dev/null +++ b/plinth/modules/radicale/privileged.py @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Configure Radicale.""" + +import os + +import augeas + +from plinth import action_utils +from plinth.actions import privileged + +CONFIG_FILE = '/etc/radicale/config' +LOG_PATH = '/var/log/radicale' + + +@privileged +def configure(rights_type: str): + """Set the radicale rights type to a particular value.""" + if rights_type == 'owner_only': + # Default rights file is equivalent to owner_only. + rights_type = 'from_file' + + aug = load_augeas() + aug.set('/files' + CONFIG_FILE + '/rights/type', rights_type) + aug.save() + + action_utils.service_try_restart('uwsgi') + + +@privileged +def fix_paths(): + """Fix log path to work around a bug.""" + # Workaround for bug in radicale's uwsgi script (#931201) + if not os.path.exists(LOG_PATH): + os.makedirs(LOG_PATH) + + +def load_augeas(): + """Initialize Augeas.""" + aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + + augeas.Augeas.NO_MODL_AUTOLOAD) + + # INI file lens + aug.set('/augeas/load/Puppet/lens', 'Puppet.lns') + aug.set('/augeas/load/Puppet/incl[last() + 1]', CONFIG_FILE) + + aug.load() + return aug diff --git a/plinth/modules/radicale/views.py b/plinth/modules/radicale/views.py index 88d56cac6..e7d73b7a6 100644 --- a/plinth/modules/radicale/views.py +++ b/plinth/modules/radicale/views.py @@ -6,10 +6,9 @@ Views for radicale module. from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth.views import AppView -from . import get_rights_value +from . import get_rights_value, privileged from .forms import RadicaleForm @@ -28,9 +27,7 @@ class RadicaleAppView(AppView): """Change the access control of Radicale service.""" data = form.cleaned_data if get_rights_value() != data['access_rights']: - actions.superuser_run( - 'radicale', - ['configure', '--rights_type', data['access_rights']]) + privileged.configure(data['access_rights']) messages.success(self.request, _('Access rights configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/roundcube/privileged.py b/plinth/modules/roundcube/privileged.py index bfcc99fe5..1fd6591ba 100644 --- a/plinth/modules/roundcube/privileged.py +++ b/plinth/modules/roundcube/privileged.py @@ -35,7 +35,7 @@ def setup(): @privileged def get_config() -> dict[str, bool]: - """Print the current configuration as JSON.""" + """Return the current configuration as a dictionary.""" pattern = r'\s*\$config\[\s*\'([^\']*)\'\s*\]\s*=\s*\'([^\']*)\'\s*;' _config = {} try: diff --git a/plinth/modules/samba/__init__.py b/plinth/modules/samba/__init__.py index 3730da2fd..cab73b3b8 100644 --- a/plinth/modules/samba/__init__.py +++ b/plinth/modules/samba/__init__.py @@ -1,17 +1,13 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure samba. -""" +"""FreedomBox app to configure samba.""" import grp -import json import pwd import socket from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.daemon import Daemon @@ -21,7 +17,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('Samba allows to share files and folders between FreedomBox and ' @@ -102,7 +98,7 @@ class SambaApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('samba', ['setup']) + privileged.setup() self.enable() @@ -112,37 +108,24 @@ class SambaBackupRestore(BackupRestore): def backup_pre(self, packet): """Save registry share configuration.""" super().backup_pre(packet) - actions.superuser_run('samba', ['dump-shares']) + privileged.dump_shares() def restore_post(self, packet): """Restore configuration.""" super().restore_post(packet) - actions.superuser_run('samba', ['setup']) - actions.superuser_run('samba', ['restore-shares']) + privileged.setup() + privileged.restore_shares() def add_share(mount_point, share_type, filesystem): """Add a share.""" - command = [ - 'add-share', '--mount-point', mount_point, '--share-type', share_type - ] - if filesystem in ['ntfs', 'vfat']: - command = command + ['--windows-filesystem'] - actions.superuser_run('samba', command) - - -def delete_share(mount_point, share_type): - """Delete a share.""" - actions.superuser_run('samba', [ - 'delete-share', '--mount-point', mount_point, '--share-type', - share_type - ]) + windows_filesystem = (filesystem in ['ntfs', 'vfat']) + privileged.add_share(mount_point, share_type, windows_filesystem) def get_users(): """Get non-system users who are in the freedombox-share or admin group.""" - output = actions.superuser_run('samba', ['get-users']) - samba_users = json.loads(output)['users'] + samba_users = privileged.get_users() group_users = grp.getgrnam('freedombox-share').gr_mem + grp.getgrnam( 'admin').gr_mem @@ -158,10 +141,3 @@ def get_users(): 'password_re_enter_needed': sorted(set(allowed_users) - set(samba_users)) } - - -def get_shares(): - """Get defined shares.""" - output = actions.superuser_run('samba', ['get-shares']) - - return json.loads(output) diff --git a/actions/samba b/plinth/modules/samba/privileged.py old mode 100755 new mode 100644 similarity index 78% rename from actions/samba rename to plinth/modules/samba/privileged.py index 991a6bbce..e91857926 --- a/actions/samba +++ b/plinth/modules/samba/privileged.py @@ -1,16 +1,13 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for samba. -""" +"""Configuration helper for samba.""" -import argparse import configparser -import json import os import shutil import subprocess +from plinth.actions import privileged + SHARES_CONF_BACKUP_FILE = '/var/lib/plinth/backups-data/samba-shares-dump.conf' DEFAULT_FILE = '/etc/default/samba' @@ -45,42 +42,6 @@ CONF = r''' ''' # noqa: E501 -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Configure samba after install') - - subparsers.add_parser('get-shares', help='Get configured samba shares') - - subparsers.add_parser('get-users', help='Get users from Samba database') - - subparser = subparsers.add_parser('add-share', help='Add new samba share') - subparser.add_argument('--mount-point', help='Path of the mount point', - required=True) - subparser.add_argument('--share-type', help='Type of the share', - required=True, choices=['open', 'group', 'home']) - subparser.add_argument('--windows-filesystem', required=False, - default=False, action='store_true', - help='Path is Windows filesystem') - - subparser = subparsers.add_parser( - 'delete-share', help='Delete a samba share configuration') - subparser.add_argument('--mount-point', help='Path of the mount point', - required=True) - subparser.add_argument('--share-type', help='Type of the share', - required=True, choices=['open', 'group', 'home']) - - subparsers.add_parser('dump-shares', - help='Dump share configuration to file') - subparsers.add_parser('restore-shares', - help='Restore share configuration from file') - - subparsers.required = True - return parser.parse_args() - - def _close_share(share_name): """Disconnect all samba users who are connected to the share.""" subprocess.check_call(['smbcontrol', 'smbd', 'close-share', share_name]) @@ -182,7 +143,7 @@ def _get_mount_point(path): return path.split(subpath)[0] -def _get_shares(): +def _get_shares() -> list[dict[str, str]]: """Get shares.""" shares = [] output = subprocess.check_output(['net', 'conf', 'list']) @@ -265,40 +226,50 @@ def _set_share_permissions(directory): subprocess.check_call(['setfacl', '-Rdm', 'g::rwX', directory]) -def subcommand_add_share(arguments): +@privileged +def add_share(mount_point: str, share_type: str, windows_filesystem: bool): """Create a samba share.""" - mount_point = os.path.normpath(arguments.mount_point) + if share_type not in ('open', 'group', 'home'): + raise ValueError('Invalid share type') + + mount_point = os.path.normpath(mount_point) if not os.path.ismount(mount_point): raise RuntimeError( 'Path "{0}" is not a mount point.'.format(mount_point)) - _create_share(mount_point, arguments.share_type, - arguments.windows_filesystem) + _create_share(mount_point, share_type, windows_filesystem) -def subcommand_delete_share(arguments): +@privileged +def delete_share(mount_point: str, share_type: str): """Delete a samba share configuration.""" - mount_point = os.path.normpath(arguments.mount_point) + if share_type not in ('open', 'group', 'home'): + raise ValueError('Invalid share type') + + mount_point = os.path.normpath(mount_point) shares = _get_shares() for share in shares: if share['mount_point'] == mount_point and share[ - 'share_type'] == arguments.share_type: + 'share_type'] == share_type: _close_share(share['name']) _conf_command(['delshare', share['name']]) -def subcommand_get_shares(_): +@privileged +def get_shares() -> list[dict[str, str]]: """Get samba shares.""" - print(json.dumps(_get_shares())) + return _get_shares() -def subcommand_get_users(_): +@privileged +def get_users() -> list[str]: """Get users from Samba database.""" output = subprocess.check_output(['pdbedit', '-L']).decode() samba_users = [line.split(':')[0] for line in output.split()] - print(json.dumps({'users': samba_users})) + return samba_users -def subcommand_setup(_): +@privileged +def setup(): """Configure samba, use custom samba config file.""" from plinth import action_utils with open(CONF_PATH, 'w', encoding='utf-8') as file_handle: @@ -310,7 +281,8 @@ def subcommand_setup(_): action_utils.service_restart('smbd') -def subcommand_dump_shares(_): +@privileged +def dump_shares(): """Dump registy share configuration.""" os.makedirs(os.path.dirname(SHARES_CONF_BACKUP_FILE), exist_ok=True) with open(SHARES_CONF_BACKUP_FILE, 'w', encoding='utf-8') as backup_file: @@ -318,22 +290,11 @@ def subcommand_dump_shares(_): subprocess.run(command, stdout=backup_file, check=True) -def subcommand_restore_shares(_): +@privileged +def restore_shares(): """Restore registy share configuration.""" if not os.path.exists(SHARES_CONF_BACKUP_FILE): raise RuntimeError( 'Backup file {0} does not exist.'.format(SHARES_CONF_BACKUP_FILE)) _conf_command(['drop']) _conf_command(['import', SHARES_CONF_BACKUP_FILE]) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/samba/tests/test_views.py b/plinth/modules/samba/tests/test_views.py index 42f97733f..70dd0c061 100644 --- a/plinth/modules/samba/tests/test_views.py +++ b/plinth/modules/samba/tests/test_views.py @@ -3,7 +3,7 @@ Tests for samba views. """ -import json +import pathlib import urllib from unittest.mock import patch @@ -12,11 +12,11 @@ from django import urls from django.contrib.messages.storage.fallback import FallbackStorage from plinth import module_loader -from plinth.errors import ActionError from plinth.modules.samba import views # For all tests, use plinth.urls instead of urls configured for testing pytestmark = pytest.mark.urls('plinth.urls') +setfacl_path = pathlib.Path('/usr/bin/setfacl') USERS = {"access_ok": ["testuser"], 'password_re_enter_needed': []} @@ -70,18 +70,12 @@ def fixture_samba_urls(): yield -def action_run(action, options, **kwargs): - """Action return values.""" - if action == 'samba' and options == ['get-shares']: - return json.dumps(SHARES) - - return None - - @pytest.fixture(autouse=True) -def samba_patch_actions(): - """Patch actions scripts runner.""" - with patch('plinth.actions.superuser_run', side_effect=action_run): +def samba_patch_privileged(): + """Patch privileged scripts runner.""" + with patch('plinth.modules.samba.privileged.get_shares') as get_shares, \ + patch('plinth.modules.samba.privileged.delete_share'): + get_shares.return_value = SHARES yield @@ -120,6 +114,7 @@ def test_samba_shares_view(rf): assert response.status_code == 200 +@pytest.mark.skipif(not setfacl_path.exists(), reason='setfacl not installed') def test_enable_samba_share_view(rf): """Test that enabling share sends correct success message.""" form_data = {'filesystem_type': 'ext4', 'open_share': 'enable'} @@ -138,7 +133,7 @@ def test_enable_samba_share_failed_view(rf): mount_point = urllib.parse.quote('/') error_message = 'Sharing failed' with patch('plinth.modules.samba.add_share', - side_effect=ActionError(error_message)): + side_effect=RuntimeError(error_message)): response, messages = make_request(rf.post('', data=form_data), views.share, mount_point=mount_point) @@ -165,13 +160,12 @@ def test_disable_samba_share_failed_view(rf): form_data = {'filesystem_type': 'ext4', 'open_share': 'disable'} mount_point = urllib.parse.quote('/') error_message = 'Unsharing failed' - with patch('plinth.modules.samba.delete_share', - side_effect=ActionError(error_message)): + with patch('plinth.modules.samba.privileged.delete_share', + side_effect=RuntimeError(error_message)): response, messages = make_request(rf.post('', data=form_data), views.share, mount_point=mount_point) - assert list( - messages)[0].message == 'Error disabling share: {0}'.format( - error_message) + assert list(messages)[ + 0].message == 'Error disabling share: {0}'.format(error_message) assert response.status_code == 302 assert response.url == urls.reverse('samba:index') diff --git a/plinth/modules/samba/views.py b/plinth/modules/samba/views.py index 17ab9d87e..5df8f70b5 100644 --- a/plinth/modules/samba/views.py +++ b/plinth/modules/samba/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for samba module. -""" +"""Views for samba module.""" import logging import os @@ -15,9 +13,10 @@ from django.utils.translation import gettext as _ from django.views.decorators.http import require_POST from plinth import views -from plinth.errors import ActionError from plinth.modules import samba, storage +from . import privileged + logger = logging.getLogger(__name__) @@ -40,6 +39,7 @@ def get_share_mounts(): class SambaAppView(views.AppView): """Samba sharing basic configuration.""" + app_id = 'samba' template_name = 'samba.html' @@ -49,7 +49,7 @@ class SambaAppView(views.AppView): disks = get_share_mounts() context['disks'] = disks - shares = samba.get_shares() + shares = privileged.get_shares() shared_mounts = defaultdict(list) for share in shares: shared_mounts[share['mount_point']].append(share['share_type']) @@ -101,7 +101,7 @@ def share(request, mount_point): try: samba.add_share(mount_point, share_type, filesystem) messages.success(request, _('Share enabled.')) - except ActionError as exception: + except Exception as exception: logger.exception('Error enabling share') messages.error( request, @@ -109,9 +109,9 @@ def share(request, mount_point): error_message=exception)) elif action == 'disable': try: - samba.delete_share(mount_point, share_type) + privileged.delete_share(mount_point, share_type) messages.success(request, _('Share disabled.')) - except ActionError as exception: + except Exception as exception: logger.exception('Error disabling share') messages.error( request, diff --git a/plinth/modules/searx/__init__.py b/plinth/modules/searx/__init__.py index 27b8fe9cb..675483d41 100644 --- a/plinth/modules/searx/__init__.py +++ b/plinth/modules/searx/__init__.py @@ -1,13 +1,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Searx. -""" +"""FreedomBox app to configure Searx.""" import os from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import frontpage, menu from plinth.modules.apache.components import Uwsgi, Webserver @@ -16,7 +13,7 @@ from plinth.modules.firewall.components import Firewall from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('Searx is a privacy-respecting Internet metasearch engine. ' @@ -95,9 +92,9 @@ class SearxApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('searx', ['setup']) + privileged.setup() if not old_version or old_version < 3: - actions.superuser_run('searx', ['disable-public-access']) + privileged.disable_public_access() self.enable() self.set_shortcut_login_required(True) @@ -115,12 +112,6 @@ class SearxWebserverAuth(Webserver): super().enable() -def get_safe_search_setting(): - """Get the current value of the safe search setting for Searx.""" - value = actions.superuser_run('searx', ['get-safe-search']) - return int(value.strip()) - - def is_public_access_enabled(): """Check whether public access is enabled for Searx.""" return os.path.exists(manifest.PUBLIC_ACCESS_SETTING_FILE) @@ -128,7 +119,7 @@ def is_public_access_enabled(): def enable_public_access(): """Allow Searx app to be accessed by anyone with access.""" - actions.superuser_run('searx', ['enable-public-access']) + privileged.enable_public_access() app = app_module.App.get('searx') app.get_component('webserver-searx-auth').disable() app.set_shortcut_login_required(False) @@ -136,7 +127,7 @@ def enable_public_access(): def disable_public_access(): """Allow Searx app to be accessed by logged-in users only.""" - actions.superuser_run('searx', ['disable-public-access']) + privileged.disable_public_access() app = app_module.App.get('searx') app.get_component('webserver-searx-auth').enable() app.set_shortcut_login_required(True) diff --git a/plinth/modules/searx/forms.py b/plinth/modules/searx/forms.py index e4cddb966..11f46cce8 100644 --- a/plinth/modules/searx/forms.py +++ b/plinth/modules/searx/forms.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Django form for configuring Searx. -""" +"""Django form for configuring Searx.""" from django import forms from django.utils.translation import gettext_lazy as _ @@ -9,6 +7,7 @@ from django.utils.translation import gettext_lazy as _ class SearxForm(forms.Form): """Searx configuration form.""" + safe_search = forms.ChoiceField( label=_('Safe Search'), help_text=_( 'Select the default family filter to apply to your search results.' diff --git a/actions/searx b/plinth/modules/searx/privileged.py old mode 100755 new mode 100644 similarity index 68% rename from actions/searx rename to plinth/modules/searx/privileged.py index 6f9aca347..9279d61b3 --- a/actions/searx +++ b/plinth/modules/searx/privileged.py @@ -1,10 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for searx. -""" +"""Configure searx.""" -import argparse import gzip import os import pathlib @@ -15,6 +11,7 @@ import augeas import yaml from plinth import action_utils +from plinth.actions import privileged from plinth.modules.searx.manifest import PUBLIC_ACCESS_SETTING_FILE from plinth.utils import gunzip @@ -23,34 +20,6 @@ SETTINGS_FILE = '/etc/searx/settings.yml' UWSGI_FILE = '/etc/uwsgi/apps-available/searx.ini' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser( - 'setup', help='Perform post-installation operations for Searx') - - subparsers.add_parser('enable-public-access', - help='Enable public access to the Searx application') - subparsers.add_parser( - 'disable-public-access', - help='Disable public access to the Searx application') - - safe_search = subparsers.add_parser( - 'set-safe-search', - help='Set the default filter for safe search on Searx') - safe_search.add_argument( - 'filter', type=int, - help='Filter results. 0: None, 1: Moderate, 2: Strict') - - subparsers.add_parser('get-safe-search', - help='Print the value of the safe search setting.') - - subparsers.required = True - return parser.parse_args() - - def _copy_uwsgi_configuration(): """Copy example uwsgi configuration @@ -100,21 +69,22 @@ def _set_safe_search(settings): settings['search']['safe_search'] = 1 -def subcommand_set_safe_search(arguments): +@privileged +def set_safe_search(filter_: int): """Set safe search filter for search results.""" - value = arguments.filter settings = read_settings() - settings['search']['safe_search'] = value + settings['search']['safe_search'] = filter_ write_settings(settings) -def subcommand_get_safe_search(_): - """Print the value of the safe search setting.""" +@privileged +def get_safe_search() -> int: + """Return the value of the safe search setting.""" if os.path.exists(SETTINGS_FILE): settings = read_settings() - print(settings['search']['safe_search']) + return int(settings['search']['safe_search']) else: - print(0) + return 0 def read_settings(): @@ -138,15 +108,16 @@ def _get_example_settings_file(): def _update_search_engines(settings): - """Updates settings with the latest supported search engines.""" + """Update settings with the latest supported search engines.""" example_settings_file = _get_example_settings_file() open_func = gzip.open if example_settings_file.suffix == '.gz' else open with open_func(example_settings_file, 'rb') as example_settings: settings['engines'] = yaml.safe_load(example_settings)['engines'] -def subcommand_setup(_): - """Post installation actions for Searx""" +@privileged +def setup(): + """Post installation actions for Searx.""" _copy_uwsgi_configuration() _update_uwsgi_configuration() @@ -169,25 +140,14 @@ def subcommand_setup(_): action_utils.service_restart('uwsgi') -def subcommand_enable_public_access(_): +@privileged +def enable_public_access(): """Enable public access to the SearX application.""" open(PUBLIC_ACCESS_SETTING_FILE, 'w', encoding='utf-8').close() -def subcommand_disable_public_access(_): +@privileged +def disable_public_access(): """Disable public access to the SearX application.""" if os.path.exists(PUBLIC_ACCESS_SETTING_FILE): os.remove(PUBLIC_ACCESS_SETTING_FILE) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/searx/views.py b/plinth/modules/searx/views.py index dbe80e658..f71e3a641 100644 --- a/plinth/modules/searx/views.py +++ b/plinth/modules/searx/views.py @@ -1,31 +1,27 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Django views for Searx. -""" +"""Django views for Searx.""" from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions -from plinth import app as app_module from plinth import views -from plinth.errors import ActionError from plinth.modules import searx +from . import privileged from .forms import SearxForm class SearxAppView(views.AppView): """Serve configuration page.""" + app_id = 'searx' form_class = SearxForm def get_initial(self): """Return the status of the service to fill in the form.""" initial = super().get_initial() - initial['safe_search'] = searx.get_safe_search_setting() - initial['public_access'] = searx.is_public_access_enabled() and \ - app_module.App.get('searx').is_enabled() + initial['safe_search'] = privileged.get_safe_search() + initial['public_access'] = searx.is_public_access_enabled() return initial def form_valid(self, form): @@ -35,10 +31,9 @@ class SearxAppView(views.AppView): if str(old_data['safe_search']) != form_data['safe_search']: try: - actions.superuser_run( - 'searx', ['set-safe-search', form_data['safe_search']]) + privileged.set_safe_search(int(form_data['safe_search'])) messages.success(self.request, _('Configuration updated.')) - except ActionError: + except Exception: messages.error(self.request, _('An error occurred during configuration.')) @@ -49,7 +44,7 @@ class SearxAppView(views.AppView): else: searx.disable_public_access() messages.success(self.request, _('Configuration updated.')) - except ActionError: + except Exception: messages.error(self.request, _('An error occurred during configuration.')) diff --git a/plinth/modules/security/__init__.py b/plinth/modules/security/__init__.py index 8f46d2990..e319dd879 100644 --- a/plinth/modules/security/__init__.py +++ b/plinth/modules/security/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for security configuration. -""" +"""FreedomBox app for security configuration.""" import re import subprocess @@ -9,20 +7,14 @@ from collections import defaultdict from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import menu from plinth.daemon import Daemon, RelatedDaemon from plinth.modules.backups.components import BackupRestore from plinth.package import Packages +from plinth.privileged import service as service_privileged -from . import manifest - -ACCESS_CONF_FILE = '/etc/security/access.d/50freedombox.conf' -ACCESS_CONF_FILE_OLD = '/etc/security/access.conf' -ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx plinth (admin) (sudo):ALL' -OLD_ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL' -ACCESS_CONF_SNIPPETS = [OLD_ACCESS_CONF_SNIPPET, ACCESS_CONF_SNIPPET] +from . import manifest, privileged class SecurityApp(app_module.App): @@ -63,46 +55,31 @@ class SecurityApp(app_module.App): if not old_version: enable_fail2ban() - actions.superuser_run('service', ['reload', 'fail2ban']) + service_privileged.reload('fail2ban') # Migrate to new config file. - enabled = get_restricted_access_enabled() + enabled = privileged.get_restricted_access_enabled() set_restricted_access(False) if enabled: set_restricted_access(True) def enable_fail2ban(): - actions.superuser_run('service', ['unmask', 'fail2ban']) - actions.superuser_run('service', ['enable', 'fail2ban']) - - -def get_restricted_access_enabled(): - """Return whether restricted access is enabled""" - with open(ACCESS_CONF_FILE_OLD, 'r', encoding='utf-8') as conffile: - if any(line.strip() in ACCESS_CONF_SNIPPETS - for line in conffile.readlines()): - return True - - try: - with open(ACCESS_CONF_FILE, 'r', encoding='utf-8') as conffile: - return any(line.strip() in ACCESS_CONF_SNIPPETS - for line in conffile.readlines()) - except FileNotFoundError: - return False + """Unmask, enable and run the fail2ban service.""" + service_privileged.unmask('fail2ban') + service_privileged.enable('fail2ban') def set_restricted_access(enabled): - """Enable or disable restricted access""" - action = 'disable-restricted-access' + """Enable or disable restricted access.""" if enabled: - action = 'enable-restricted-access' - - actions.superuser_run('security', [action]) + privileged.enable_restricted_access() + else: + privileged.disable_restricted_access() def get_apps_report(): - """Return a security report for each app""" + """Return a security report for each app.""" lines = subprocess.check_output(['debsecan']).decode().split('\n') cves = defaultdict(set) for line in lines: diff --git a/plinth/modules/security/data/etc/fail2ban/fail2ban.d/freedombox.conf b/plinth/modules/security/data/etc/fail2ban/fail2ban.d/freedombox.conf new file mode 100644 index 000000000..277d4a0ad --- /dev/null +++ b/plinth/modules/security/data/etc/fail2ban/fail2ban.d/freedombox.conf @@ -0,0 +1,2 @@ +[DEFAULT] +logtarget = sysout diff --git a/plinth/modules/security/privileged.py b/plinth/modules/security/privileged.py new file mode 100644 index 000000000..b59a8f6fb --- /dev/null +++ b/plinth/modules/security/privileged.py @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Helper for security configuration.""" + +import os + +from plinth.actions import privileged + +ACCESS_CONF_FILE = '/etc/security/access.d/50freedombox.conf' +ACCESS_CONF_FILE_OLD = '/etc/security/access.conf' +ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx plinth (admin) (sudo):ALL' +OLD_ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx (admin) (sudo):ALL' +ACCESS_CONF_SNIPPETS = [OLD_ACCESS_CONF_SNIPPET, ACCESS_CONF_SNIPPET] + + +@privileged +def enable_restricted_access(): + """Restrict console login to users in admin or sudo group.""" + try: + os.mkdir(os.path.dirname(ACCESS_CONF_FILE)) + except FileExistsError: + pass + + with open(ACCESS_CONF_FILE, 'w', encoding='utf-8') as conffile: + conffile.write(ACCESS_CONF_SNIPPET + '\n') + + +@privileged +def disable_restricted_access(): + """Don't restrict console login to users in admin or sudo group.""" + with open(ACCESS_CONF_FILE_OLD, 'r', encoding='utf-8') as conffile: + lines = conffile.readlines() + + with open(ACCESS_CONF_FILE_OLD, 'w', encoding='utf-8') as conffile: + for line in lines: + if line.strip() not in ACCESS_CONF_SNIPPETS: + conffile.write(line) + + try: + os.remove(ACCESS_CONF_FILE) + except OSError: + pass + + +def get_restricted_access_enabled(): + """Return whether restricted access is enabled.""" + with open(ACCESS_CONF_FILE_OLD, 'r', encoding='utf-8') as conffile: + if any(line.strip() in ACCESS_CONF_SNIPPETS + for line in conffile.readlines()): + return True + + try: + with open(ACCESS_CONF_FILE, 'r', encoding='utf-8') as conffile: + return any(line.strip() in ACCESS_CONF_SNIPPETS + for line in conffile.readlines()) + except FileNotFoundError: + return False diff --git a/plinth/modules/security/views.py b/plinth/modules/security/views.py index 0831698d2..6a24fc87d 100644 --- a/plinth/modules/security/views.py +++ b/plinth/modules/security/views.py @@ -1,17 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for security module -""" +"""Views for security module.""" from django.contrib import messages from django.template.response import TemplateResponse from django.utils.translation import gettext as _ -from plinth import action_utils, actions +from plinth import action_utils from plinth.modules import security from plinth.modules.upgrades import is_backports_requested +from plinth.privileged import service as service_privileged from plinth.views import AppView +from . import privileged from .forms import SecurityForm @@ -42,15 +42,15 @@ class SecurityAppView(AppView): def get_status(request): - """Return the current status""" + """Return the current status.""" return { - 'restricted_access': security.get_restricted_access_enabled(), + 'restricted_access': privileged.get_restricted_access_enabled(), 'fail2ban_enabled': action_utils.service_is_enabled('fail2ban') } def _apply_changes(request, old_status, new_status): - """Apply the form changes""" + """Apply the form changes.""" if old_status['restricted_access'] != new_status['restricted_access']: try: security.set_restricted_access(new_status['restricted_access']) @@ -64,13 +64,13 @@ def _apply_changes(request, old_status, new_status): if old_status['fail2ban_enabled'] != new_status['fail2ban_enabled']: if new_status['fail2ban_enabled']: - actions.superuser_run('service', ['enable', 'fail2ban']) + service_privileged.enable('fail2ban') else: - actions.superuser_run('service', ['disable', 'fail2ban']) + service_privileged.disable('fail2ban') def report(request): - """Serve the security report page""" + """Serve the security report page.""" apps_report = security.get_apps_report() return TemplateResponse( request, 'security_report.html', { diff --git a/plinth/modules/shadowsocks/__init__.py b/plinth/modules/shadowsocks/__init__.py index b91cb6e47..c0d45df36 100644 --- a/plinth/modules/shadowsocks/__init__.py +++ b/plinth/modules/shadowsocks/__init__.py @@ -1,12 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Shadowsocks. -""" +"""FreedomBox app to configure Shadowsocks.""" from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -15,7 +12,7 @@ from plinth.modules.firewall.components import Firewall from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to ' @@ -85,5 +82,5 @@ class ShadowsocksApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('shadowsocks', ['setup']) + privileged.setup() self.enable() diff --git a/plinth/modules/shadowsocks/forms.py b/plinth/modules/shadowsocks/forms.py index 188e4caf5..102b77baf 100644 --- a/plinth/modules/shadowsocks/forms.py +++ b/plinth/modules/shadowsocks/forms.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring Shadowsocks. -""" +"""FreedomBox app for configuring Shadowsocks.""" from django import forms from django.utils.translation import gettext_lazy as _ @@ -22,10 +20,10 @@ METHODS = [('chacha20-ietf-poly1305', class TrimmedCharField(forms.CharField): - """Trim the contents of a CharField""" + """Trim the contents of a CharField.""" def clean(self, value): - """Clean and validate the field value""" + """Clean and validate the field value.""" if value: value = value.strip() @@ -33,7 +31,8 @@ class TrimmedCharField(forms.CharField): class ShadowsocksForm(forms.Form): - """Shadowsocks configuration form""" + """Shadowsocks configuration form.""" + server = TrimmedCharField(label=_('Server'), help_text=_('Server hostname or IP address')) diff --git a/actions/shadowsocks b/plinth/modules/shadowsocks/privileged.py old mode 100755 new mode 100644 similarity index 70% rename from actions/shadowsocks rename to plinth/modules/shadowsocks/privileged.py index 1407dadf6..39cdbe6b4 --- a/actions/shadowsocks +++ b/plinth/modules/shadowsocks/privileged.py @@ -1,42 +1,24 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Helper script for configuring Shadowsocks. -""" +"""Configure Shadowsocks.""" -import argparse import json import os import pathlib import random import string -import sys from shutil import move +from typing import Union from plinth import action_utils -from plinth.modules.shadowsocks import ShadowsocksApp +from plinth.actions import privileged SHADOWSOCKS_CONFIG_SYMLINK = '/etc/shadowsocks-libev/freedombox.json' SHADOWSOCKS_CONFIG_ACTUAL = \ '/var/lib/private/shadowsocks-libev/freedombox/freedombox.json' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - 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.required = True - return parser.parse_args() - - -def subcommand_setup(_): +@privileged +def setup(): """Perform initial setup steps.""" # Only client socks5 proxy is supported for now. Disable the # server component. @@ -76,16 +58,16 @@ def subcommand_setup(_): if not wrong_state_dir.is_symlink() and wrong_state_dir.is_dir(): wrong_state_dir.rmdir() + from plinth.modules.shadowsocks import ShadowsocksApp if action_utils.service_is_enabled(ShadowsocksApp.DAEMON): action_utils.service_restart(ShadowsocksApp.DAEMON) -def subcommand_get_config(_): +@privileged +def get_config() -> dict[str, Union[int, str]]: """Read and print Shadowsocks configuration.""" - try: - print(open(SHADOWSOCKS_CONFIG_SYMLINK, 'r', encoding='utf-8').read()) - except Exception: - sys.exit(1) + config = open(SHADOWSOCKS_CONFIG_SYMLINK, 'r', encoding='utf-8').read() + return json.loads(config) def _merge_config(config): @@ -103,26 +85,13 @@ def _merge_config(config): open(SHADOWSOCKS_CONFIG_SYMLINK, 'w', encoding='utf-8').write(new_config) -def subcommand_merge_config(_): +@privileged +def merge_config(config: dict[str, Union[int, str]]): """Configure Shadowsocks.""" - config = sys.stdin.read() - config = json.loads(config) _merge_config(config) # Don't try_restart because initial configuration may not be valid so # shadowsocks will not be running even when enabled. + from . import ShadowsocksApp if action_utils.service_is_enabled(ShadowsocksApp.DAEMON): action_utils.service_restart(ShadowsocksApp.DAEMON) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/shadowsocks/views.py b/plinth/modules/shadowsocks/views.py index b1d8b74fd..ad2deda1b 100644 --- a/plinth/modules/shadowsocks/views.py +++ b/plinth/modules/shadowsocks/views.py @@ -1,21 +1,18 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring Shadowsocks. -""" - -import json +"""FreedomBox app for configuring Shadowsocks.""" from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from plinth import actions, views -from plinth.errors import ActionError +from plinth import views +from . import privileged from .forms import ShadowsocksForm class ShadowsocksAppView(views.AppView): """Configuration view for Shadowsocks local socks5 proxy.""" + app_id = 'shadowsocks' form_class = ShadowsocksForm @@ -23,10 +20,8 @@ class ShadowsocksAppView(views.AppView): """Get initial values for form.""" status = super().get_initial() try: - configuration = actions.superuser_run('shadowsocks', - ['get-config']) - status.update(json.loads(configuration)) - except ActionError: + status.update(privileged.get_config()) + except Exception: status.update({ 'server': '', 'server_port': 8388, @@ -54,8 +49,7 @@ class ShadowsocksAppView(views.AppView): 'method': new_status['method'], } - actions.superuser_run('shadowsocks', ['merge-config'], - input=json.dumps(new_config).encode()) + privileged.merge_config(new_config) messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/sharing/__init__.py b/plinth/modules/sharing/__init__.py index 1ce644648..6a0c53e9e 100644 --- a/plinth/modules/sharing/__init__.py +++ b/plinth/modules/sharing/__init__.py @@ -1,13 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure sharing. -""" - -import json +"""FreedomBox app to configure sharing.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu from plinth.modules.apache.components import Webserver @@ -60,22 +55,3 @@ class SharingApp(app_module.App): super().setup(old_version) privileged.setup() self.enable() - - -def list_shares(): - """Return a list of shares.""" - output = actions.superuser_run('sharing', ['list']) - return json.loads(output)['shares'] - - -def add_share(name, path, groups, is_public): - """Add a new share by called the action script.""" - args = ['add', '--name', name, '--path', path, '--groups'] + groups - if is_public: - args.append('--is-public') - actions.superuser_run('sharing', args) - - -def remove_share(name): - """Remove a share by calling the action script.""" - actions.superuser_run('sharing', ['remove', '--name', name]) diff --git a/plinth/modules/sharing/forms.py b/plinth/modules/sharing/forms.py index e9a50a8c3..1416a0e27 100644 --- a/plinth/modules/sharing/forms.py +++ b/plinth/modules/sharing/forms.py @@ -1,15 +1,14 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Django forms for sharing app. -""" +"""Django forms for sharing app.""" from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ -from plinth.modules import sharing from plinth.modules.users.components import UsersAndGroups +from . import privileged + class AddShareForm(forms.Form): """Form to add a new share.""" @@ -47,7 +46,7 @@ class AddShareForm(forms.Form): if 'name' in self.initial and name == self.initial['name']: return name - if any((share for share in sharing.list_shares() + if any((share for share in privileged.list_shares() if name == share['name'])): raise ValidationError(_('A share with this name already exists.')) diff --git a/plinth/modules/sharing/privileged.py b/plinth/modules/sharing/privileged.py index 79c247f07..bfc2745ec 100644 --- a/plinth/modules/sharing/privileged.py +++ b/plinth/modules/sharing/privileged.py @@ -1,8 +1,13 @@ # SPDX-License-Identifier: AGPL-3.0-or-later """Configure sharing.""" +import os import pathlib +import re +import augeas + +from plinth import action_utils from plinth.actions import privileged APACHE_CONFIGURATION = '/etc/apache2/conf-available/sharing-freedombox.conf' @@ -14,3 +19,157 @@ def setup(): path = pathlib.Path(APACHE_CONFIGURATION) if not path.exists(): path.touch() + + +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.set('/augeas/load/Httpd/lens', 'Httpd.lns') + aug.set('/augeas/load/Httpd/incl[last() + 1]', APACHE_CONFIGURATION) + aug.load() + + aug.defvar('conf', '/files' + APACHE_CONFIGURATION) + + return aug + + +@privileged +def add(name: str, path: str, groups: list[str], is_public: bool): + """Add a share to Apache configuration.""" + path = '"' + path.replace('"', r'\"') + '"' + url = '/share/' + name + + if not os.path.exists(APACHE_CONFIGURATION): + pathlib.Path(APACHE_CONFIGURATION).touch() + + aug = load_augeas() + shares = _list(aug) + if any([share for share in shares if share['name'] == name]): + raise Exception('Share already present') + + aug.set('$conf/directive[last() + 1]', 'Alias') + aug.set('$conf/directive[last()]/arg[1]', url) + aug.set('$conf/directive[last()]/arg[2]', path) + + aug.set('$conf/Location[last() + 1]/arg', url) + + aug.set('$conf/Location[last()]/directive[last() + 1]', 'Include') + aug.set('$conf/Location[last()]/directive[last()]/arg', + 'includes/freedombox-sharing.conf') + + if not is_public: + aug.set('$conf/Location[last()]/directive[last() + 1]', 'Include') + aug.set('$conf/Location[last()]/directive[last()]/arg', + 'includes/freedombox-single-sign-on.conf') + + aug.set('$conf/Location[last()]/IfModule/arg', 'mod_auth_pubtkt.c') + aug.set('$conf/Location[last()]/IfModule/directive[1]', 'TKTAuthToken') + for group_name in groups: + aug.set( + '$conf/Location[last()]/IfModule/directive[1]/arg[last() + 1]', + group_name) + else: + aug.set('$conf/Location[last()]/directive[last() + 1]', 'Require') + aug.set('$conf/Location[last()]/directive[last()]/arg[1]', 'all') + aug.set('$conf/Location[last()]/directive[last()]/arg[2]', 'granted') + + aug.save() + + with action_utils.WebserverChange() as webserver_change: + webserver_change.enable('sharing-freedombox') + + +@privileged +def remove(name: str): + """Remove a share from Apache configuration.""" + url_to_remove = '/share/' + name + + aug = load_augeas() + + for directive in aug.match('$conf/directive'): + if aug.get(directive) != 'Alias': + continue + + url = aug.get(directive + '/arg[1]') + if url == url_to_remove: + aug.remove(directive) + + for location in aug.match('$conf/Location'): + url = aug.get(location + '/arg') + if url == url_to_remove: + aug.remove(location) + + aug.save() + + with action_utils.WebserverChange() as webserver_change: + webserver_change.enable('sharing-freedombox') + + +def _get_name_from_url(url): + """Return the name of the share given the URL for it.""" + matches = re.match(r'/share/([a-z0-9\-]*)', url) + if not matches: + raise ValueError + + return matches[1] + + +def _list(aug=None): + """List all Apache configuration shares.""" + if not aug: + aug = load_augeas() + + shares = [] + + for match in aug.match('$conf/directive'): + if aug.get(match) != 'Alias': + continue + + url = aug.get(match + '/arg[1]') + path = aug.get(match + '/arg[2]') + + path = path.removesuffix('"').removeprefix('"') + path = path.replace(r'\"', '"') + try: + name = _get_name_from_url(url) + shares.append({ + 'name': name, + 'path': path, + 'url': '/share/' + name + }) + except ValueError: + continue + + for location in aug.match('$conf/Location'): + url = aug.get(location + '/arg') + + try: + name = _get_name_from_url(url) + except ValueError: + continue + + groups = [] + for group in aug.match(location + '//directive["TKTAuthToken"]/arg'): + groups.append(aug.get(group)) + + def _is_public(): + """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' + + for share in shares: + if share['name'] == name: + share['groups'] = groups + share['is_public'] = _is_public() + + return shares + + +@privileged +def list_shares() -> list[dict[str, object]]: + """List all Apache configuration shares and print as JSON.""" + return _list() diff --git a/plinth/modules/sharing/views.py b/plinth/modules/sharing/views.py index e317244fd..28d75deff 100644 --- a/plinth/modules/sharing/views.py +++ b/plinth/modules/sharing/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the sharing app. -""" +"""Views for the sharing app.""" from django.contrib import messages from django.contrib.messages.views import SuccessMessageMixin @@ -12,26 +10,28 @@ from django.utils.translation import gettext_lazy as _ from django.views.decorators.http import require_POST from django.views.generic import FormView -from plinth.modules import sharing from plinth.views import AppView +from . import privileged from .forms import AddShareForm class SharingAppView(AppView): """Sharing configuration page.""" + app_id = 'sharing' template_name = 'sharing.html' def get_context_data(self, **kwargs): """Return additional context for rendering the template.""" context = super().get_context_data(**kwargs) - context['shares'] = sharing.list_shares() + context['shares'] = privileged.list_shares() return context class AddShareView(SuccessMessageMixin, FormView): """View to add a new share.""" + form_class = AddShareForm prefix = 'sharing' template_name = 'sharing_add_edit.html' @@ -52,6 +52,7 @@ class AddShareView(SuccessMessageMixin, FormView): class EditShareView(SuccessMessageMixin, FormView): """View to edit an existing share.""" + form_class = AddShareForm prefix = 'sharing' template_name = 'sharing_add_edit.html' @@ -68,7 +69,7 @@ class EditShareView(SuccessMessageMixin, FormView): """Load information about share being edited.""" try: return [ - share for share in sharing.list_shares() + share for share in privileged.list_shares() if share['name'] == self.kwargs['name'] ][0] except IndexError: @@ -77,20 +78,20 @@ class EditShareView(SuccessMessageMixin, FormView): def form_valid(self, form): """Add the share on valid form submission.""" if form.initial != form.cleaned_data: - sharing.remove_share(form.initial['name']) + privileged.remove(form.initial['name']) _add_share(form.cleaned_data) return super().form_valid(form) def _add_share(form_data): - sharing.add_share(form_data['name'], form_data['path'], - form_data['groups'], form_data['is_public']) + privileged.add(form_data['name'], form_data['path'], form_data['groups'], + form_data['is_public']) @require_POST def remove(request, name): """View to remove a share.""" - sharing.remove_share(name) + privileged.remove(name) messages.success(request, _('Share deleted.')) return redirect(reverse_lazy('sharing:index')) diff --git a/plinth/modules/snapshot/__init__.py b/plinth/modules/snapshot/__init__.py index c16ccb4d6..d1e6ddf4d 100644 --- a/plinth/modules/snapshot/__init__.py +++ b/plinth/modules/snapshot/__init__.py @@ -1,22 +1,18 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to manage filesystem snapshots. -""" +"""FreedomBox app to manage filesystem snapshots.""" -import json import pathlib import augeas from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import menu from plinth.modules import storage from plinth.modules.backups.components import BackupRestore from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('Snapshots allows creating and managing btrfs file system snapshots. ' @@ -71,9 +67,7 @@ class SnapshotApp(app_module.App): """Install and configure the app.""" super().setup(old_version) if is_supported(): - actions.superuser_run('snapshot', - ['setup', '--old-version', - str(old_version)]) + privileged.setup(old_version) self.enable() @@ -82,7 +76,7 @@ class SnapshotBackupRestore(BackupRestore): def restore_post(self, packet): """Run after restore.""" - actions.superuser_run('snapshot', ['kill-daemon']) + privileged.kill_daemon() def is_supported(): @@ -114,9 +108,9 @@ def is_apt_snapshots_enabled(aug): def get_configuration(): + """Return snapper configuration.""" aug = load_augeas() - output = actions.superuser_run('snapshot', ['get-config']) - output = json.loads(output) + output = privileged.get_config() def get_boolean_choice(status): return ('yes', 'Enabled') if status else ('no', 'Disabled') diff --git a/actions/snapshot b/plinth/modules/snapshot/privileged.py old mode 100755 new mode 100644 similarity index 72% rename from actions/snapshot rename to plinth/modules/snapshot/privileged.py index f74513089..f0d18e24a --- a/actions/snapshot +++ b/plinth/modules/snapshot/privileged.py @@ -1,11 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for filesystem snapshots. -""" +"""Configuration helper for filesystem snapshots.""" -import argparse -import json import os import signal import subprocess @@ -13,46 +8,15 @@ import subprocess import augeas import dbus +from plinth.actions import privileged + FSTAB = '/etc/fstab' AUG_FSTAB = '/files/etc/fstab' DEFAULT_FILE = '/etc/default/snapper' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparser = subparsers.add_parser('setup', help='Configure snapper') - subparser.add_argument( - '--old-version', type=int, required=True, - help='Earlier version of the app that is already setup.') - subparsers.add_parser('list', help='List snapshots') - subparsers.add_parser('create', help='Create snapshot') - subparsers.add_parser('get-config', help='Configurations of snapshot') - - subparser = subparsers.add_parser('delete', - help='Delete a snapshot by number') - subparser.add_argument('number', help='Number of snapshot to delete') - - subparser = subparsers.add_parser('set-config', - help='Configure automatic snapshots') - subparser.add_argument('config') - subparsers.add_parser('kill-daemon', - help='Kill snapperd to reload configuration') - - subparser = subparsers.add_parser('rollback', help='Rollback to snapshot') - subparser.add_argument('number', help='Number of snapshot to rollback to') - - subparser = subparsers.add_parser('disable-apt-snapshot', - help='enable/disable apt snapshots') - subparser.add_argument('state') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_setup(arguments): +@privileged +def setup(old_version: int): """Configure snapper.""" # Check if root config exists. command = ['snapper', 'list-configs'] @@ -65,9 +29,9 @@ def subcommand_setup(arguments): subprocess.run(command, check=True) _add_fstab_entry('/') - if arguments.old_version == 0: + if old_version == 0: _set_default_config() - elif arguments.old_version <= 3: + elif old_version <= 3: _migrate_config_from_version_3() else: pass # After version 4 and above don't reset configuration @@ -170,7 +134,8 @@ def _parse_number(number): return number.strip('-+*'), is_default, is_active -def subcommand_list(_): +@privileged +def list_() -> list[dict[str, str]]: """List snapshots.""" process = subprocess.run(['snapper', 'list'], stdout=subprocess.PIPE, check=True) @@ -189,7 +154,7 @@ def subcommand_list(_): snapshots.append(snapshot) snapshots.reverse() - print(json.dumps(snapshots)) + return snapshots def _get_default_snapshot(): @@ -208,8 +173,9 @@ def _get_default_snapshot(): return None -def subcommand_disable_apt_snapshot(arguments): - """Set flag to Enable/Disable apt software snapshots in config files""" +@privileged +def disable_apt_snapshot(state: str): + """Set flag to Enable/Disable apt software snapshots in config files.""" # Initialize Augeas aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD) @@ -217,24 +183,28 @@ def subcommand_disable_apt_snapshot(arguments): aug.set('/augeas/load/Shellvars/incl[last() + 1]', DEFAULT_FILE) aug.load() - aug.set('/files' + DEFAULT_FILE + '/DISABLE_APT_SNAPSHOT', arguments.state) + aug.set('/files' + DEFAULT_FILE + '/DISABLE_APT_SNAPSHOT', state) aug.save() -def subcommand_create(_): +@privileged +def create(): """Create snapshot.""" command = ['snapper', 'create', '--description', 'manually created'] subprocess.run(command, check=True) -def subcommand_delete(arguments): +@privileged +def delete(number: str): """Delete a snapshot by number.""" - command = ['snapper', 'delete', arguments.number] + command = ['snapper', 'delete', number] subprocess.run(command, check=True) -def subcommand_set_config(arguments): - command = ['snapper', 'set-config'] + arguments.config.split() +@privileged +def set_config(config: list[str]): + """Set snapper configuration.""" + command = ['snapper', 'set-config'] + config subprocess.run(command, check=True) @@ -249,12 +219,14 @@ def _get_config(): return config -def subcommand_get_config(_): - config = _get_config() - print(json.dumps(config)) +@privileged +def get_config() -> dict[str, str]: + """Return snapper configuration.""" + return _get_config() -def subcommand_kill_daemon(_): +@privileged +def kill_daemon(): """Kill the snapper daemon. This is generally not necessary because we do configuration changes via @@ -262,7 +234,6 @@ def subcommand_kill_daemon(_): need to kill the daemon to reload configuration. Ideally, we should be able to reload/terminate the service using systemd. - """ bus = dbus.SystemBus() @@ -277,23 +248,10 @@ def subcommand_kill_daemon(_): os.kill(pid, signal.SIGTERM) -def subcommand_rollback(arguments): +@privileged +def rollback(number: str): """Rollback to snapshot.""" command = [ - 'snapper', 'rollback', '--description', 'created by rollback', - arguments.number + 'snapper', 'rollback', '--description', 'created by rollback', number ] subprocess.run(command, check=True) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/snapshot/views.py b/plinth/modules/snapshot/views.py index e40df217a..86f892f76 100644 --- a/plinth/modules/snapshot/views.py +++ b/plinth/modules/snapshot/views.py @@ -1,9 +1,6 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for snapshot module. -""" +"""Views for snapshot module.""" -import json import urllib.parse from django.contrib import messages @@ -14,14 +11,12 @@ from django.urls import reverse, reverse_lazy from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy -from plinth import actions from plinth import app as app_module -from plinth.errors import ActionError from plinth.modules import snapshot as snapshot_module from plinth.modules import storage from plinth.views import AppView -from . import get_configuration +from . import get_configuration, privileged from .forms import SnapshotForm # i18n for snapshot descriptions @@ -90,7 +85,7 @@ def manage(request): if request.method == 'POST': if 'create' in request.POST: - actions.superuser_run('snapshot', ['create']) + privileged.create() messages.success(request, _('Created snapshot.')) if 'delete_selected' in request.POST: to_delete = request.POST.getlist('snapshot_list') @@ -102,8 +97,7 @@ def manage(request): url = reverse('snapshot:delete-selected') return HttpResponseRedirect(f'{url}?{params}') - output = actions.superuser_run('snapshot', ['list']) - snapshots = json.loads(output) + snapshots = privileged.list_() has_deletable_snapshots = any([ snapshot for snapshot in snapshots if not snapshot['is_default'] and not snapshot['is_active'] @@ -148,15 +142,14 @@ def update_configuration(request, old_status, new_status): if old_status['enable_software_snapshots'] != new_status[ 'enable_software_snapshots']: if new_status['enable_software_snapshots'] == 'yes': - actions.superuser_run('snapshot', ['disable-apt-snapshot', 'no']) + privileged.disable_apt_snapshot('no') else: - actions.superuser_run('snapshot', ['disable-apt-snapshot', 'yes']) + privileged.disable_apt_snapshot('yes') try: - actions.superuser_run('snapshot', ['set-config', " ".join(config)]) - + privileged.set_config(list(config)) messages.success(request, _('Storage snapshots configuration updated')) - except ActionError as exception: + except Exception as exception: messages.error( request, _('Action error: {0} [{1}] [{2}]').format(exception.args[0], @@ -174,8 +167,7 @@ def delete_selected(request): if not to_delete: return redirect(reverse('snapshot:manage')) - output = actions.superuser_run('snapshot', ['list']) - snapshots = json.loads(output) + snapshots = privileged.list_() snapshots_to_delete = [ snapshot for snapshot in snapshots if snapshot['number'] in to_delete and not snapshot['is_active'] and not snapshot['is_default'] @@ -184,11 +176,10 @@ def delete_selected(request): if request.method == 'POST': try: for snapshot in snapshots_to_delete: - actions.superuser_run('snapshot', - ['delete', snapshot['number']]) + privileged.delete(snapshot['number']) messages.success(request, _('Deleted selected snapshots')) - except ActionError as exception: + except Exception as exception: if 'Config is in use.' in exception.args[2]: messages.error( request, @@ -208,7 +199,7 @@ def delete_selected(request): def rollback(request, number): """Show confirmation to rollback to a snapshot.""" if request.method == 'POST': - actions.superuser_run('snapshot', ['rollback', number]) + privileged.rollback(number) messages.success( request, _('Rolled back to snapshot #{number}.').format(number=number)) @@ -217,9 +208,7 @@ def rollback(request, number): _('The system must be restarted to complete the rollback.')) return redirect(reverse('power:restart')) - output = actions.superuser_run('snapshot', ['list']) - snapshots = json.loads(output) - + snapshots = privileged.list_() snapshot = None for current_snapshot in snapshots: if current_snapshot['number'] == number: diff --git a/plinth/modules/ssh/__init__.py b/plinth/modules/ssh/__init__.py index 13e358aa6..e5e40a6dc 100644 --- a/plinth/modules/ssh/__init__.py +++ b/plinth/modules/ssh/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for OpenSSH server. -""" +"""FreedomBox app for OpenSSH server.""" import pathlib import re @@ -9,7 +7,6 @@ import subprocess from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import menu from plinth.daemon import Daemon @@ -17,7 +14,7 @@ from plinth.modules.backups.components import BackupRestore from plinth.modules.firewall.components import Firewall from plinth.package import Packages -from . import manifest +from . import manifest, privileged _description = [ _('A Secure Shell server uses the secure shell protocol to accept ' @@ -65,7 +62,7 @@ class SSHApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('ssh', ['setup']) + privileged.setup() self.enable() @@ -87,9 +84,3 @@ def get_host_keys(): host_keys.append(match.groupdict()) return host_keys - - -def is_password_authentication_disabled(): - """Return if ssh password authentication is enabled.""" - return actions.superuser_run('ssh', - ['get-password-config']).strip() == 'no' diff --git a/actions/ssh b/plinth/modules/ssh/privileged.py old mode 100755 new mode 100644 similarity index 52% rename from actions/ssh rename to plinth/modules/ssh/privileged.py index acf0d5fea..ee95983b0 --- a/actions/ssh +++ b/plinth/modules/ssh/privileged.py @@ -1,52 +1,20 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for SSH server. -""" +"""Configuration helper for SSH server.""" -import argparse import grp import os import pwd import shutil import stat import subprocess -import sys import augeas from plinth import action_utils, utils +from plinth.actions import privileged -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Setup SSH server') - - get_keys = subparsers.add_parser('get-keys', - help='Get SSH authorized keys') - get_keys.add_argument('--username', required=True, type=_managed_user) - - set_keys = subparsers.add_parser('set-keys', - help='Set SSH authorized keys') - set_keys.add_argument('--username', required=True, type=_managed_user) - set_keys.add_argument('--keys', required=True) - set_keys.add_argument('--auth-user', required=True) - - subparsers.add_parser('get-password-config', - help='Get SSH password auth configuration') - - set_password_config = subparsers.add_parser( - 'set-password-config', help='Set SSH password auth configuration') - set_password_config.add_argument('--value') - - subparsers.required = True - return parser.parse_args() - - -def _validate_user(username, must_be_admin=True): +def _validate_user(username, password, must_be_admin=True): """Validate a user.""" if must_be_admin: try: @@ -55,29 +23,23 @@ def _validate_user(username, must_be_admin=True): admins = [] if username not in admins: - msg = '"{}" is not authorized to perform this action'.format( - username) - raise argparse.ArgumentTypeError(msg) + msg = f'"{username}" is not authorized to perform this action' + raise PermissionError(msg) - password = _read_password() if not utils.is_authenticated_user(username, password): - raise argparse.ArgumentTypeError("Invalid credentials") + raise PermissionError('Invalid credentials') def _managed_user(username): """Raise an error if the user is root.""" if pwd.getpwnam(username).pw_gid == 0: - msg = 'User {} is not managed by FreedomBox'.format(username) - raise argparse.ArgumentTypeError(msg) + raise ValueError(f'User {username} is not managed by FreedomBox') + return username -def _read_password(): - """Read the password from stdin.""" - return ''.join(sys.stdin) - - -def subcommand_setup(arguments): +@privileged +def setup(): """Setup Open SSH server. Regenerates deleted SSH keys. This is necessary when FreedomBox image is @@ -87,7 +49,6 @@ def subcommand_setup(arguments): If the keys already exist, do nothing. This is necessary when a user installs FreedomBox using an apt package. SSH keys exist and running reconfigure on the openssh-server package does not regenerate them. - """ action_utils.dpkg_reconfigure('openssh-server', {}) @@ -97,29 +58,25 @@ def get_user_homedir(username): try: return pwd.getpwnam(username).pw_dir except KeyError: - print('Username not found') - sys.exit(1) + raise ValueError('Username not found') -def subcommand_get_keys(arguments): +@privileged +def get_keys(user: str) -> str: """Get SSH authorized keys.""" - user = arguments.username - path = os.path.join(get_user_homedir(user), '.ssh', 'authorized_keys') try: with open(path, 'r', encoding='utf-8') as file_handle: - print(file_handle.read()) + return file_handle.read() except FileNotFoundError: - pass + return '' -def subcommand_set_keys(arguments): +@privileged +def set_keys(user: str, keys: str, auth_user: str, auth_password: str): """Set SSH authorized keys.""" - user = arguments.username - auth_user = arguments.auth_user - must_be_admin = user != auth_user - _validate_user(auth_user, must_be_admin=must_be_admin) + _validate_user(auth_user, auth_password, must_be_admin=must_be_admin) ssh_folder = os.path.join(get_user_homedir(user), '.ssh') key_file_path = os.path.join(ssh_folder, 'authorized_keys') @@ -131,7 +88,7 @@ def subcommand_set_keys(arguments): shutil.chown(ssh_folder, user, 'users') with open(key_file_path, 'w', encoding='utf-8') as file_handle: - file_handle.write(arguments.keys) + file_handle.write(keys) shutil.chown(key_file_path, user, 'users') os.chmod(key_file_path, stat.S_IRUSR | stat.S_IWUSR) @@ -148,30 +105,19 @@ def _load_augeas(): return aug -def subcommand_get_password_config(_): +@privileged +def is_password_authentication_enabled() -> bool: """Retrieve value of password authentication from sshd configuration.""" aug = _load_augeas() field_path = '/files/etc/ssh/sshd_config/PasswordAuthentication' get_value = aug.get(field_path) - print(get_value or 'yes') + return (get_value or 'yes') == 'yes' -def subcommand_set_password_config(arguments): +@privileged +def set_password_authentication(enable: bool): """Set value of password authentication in sshd configuration.""" + value = 'yes' if enable else 'no' aug = _load_augeas() - aug.set('/files/etc/ssh/sshd_config/PasswordAuthentication', - arguments.value) + aug.set('/files/etc/ssh/sshd_config/PasswordAuthentication', value) aug.save() - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/ssh/views.py b/plinth/modules/ssh/views.py index ebddcf3d3..b1f84a231 100644 --- a/plinth/modules/ssh/views.py +++ b/plinth/modules/ssh/views.py @@ -1,40 +1,43 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the SSH module -""" +"""Views for the SSH app.""" + from django.contrib import messages from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth.modules import ssh +from plinth.privileged import service as service_privileged from plinth.views import AppView -from . import is_password_authentication_disabled +from . import privileged from .forms import SSHServerForm class SshAppView(AppView): + """Show ssh app main page.""" + app_id = 'ssh' template_name = 'ssh.html' form_class = SSHServerForm def get_context_data(self, *args, **kwargs): + """Return additional context for rendering the template.""" context = super().get_context_data(**kwargs) context['host_keys'] = ssh.get_host_keys() return context def get_initial(self): - """Initial form value""" + """Return initial values of the form.""" initial = super().get_initial() initial.update({ - 'password_auth_disabled': is_password_authentication_disabled(), + 'password_auth_disabled': + not privileged.is_password_authentication_enabled(), }) return initial def form_valid(self, form): - """Apply changes from the form""" + """Apply changes from the form.""" old_config = self.get_initial() new_config = form.cleaned_data @@ -43,16 +46,9 @@ class SshAppView(AppView): passwd_auth_changed = is_field_changed('password_auth_disabled') if passwd_auth_changed: - if new_config['password_auth_disabled']: - passwd_auth = 'no' - message = _('SSH authentication with password disabled.') - else: - passwd_auth = 'yes' - message = _('SSH authentication with password enabled.') - - actions.superuser_run( - 'ssh', ['set-password-config', '--value', passwd_auth]) - actions.superuser_run('service', ['reload', 'ssh']) - messages.success(self.request, message) + privileged.set_password_authentication( + not new_config['password_auth_disabled']) + service_privileged.reload('ssh') + messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/sso/__init__.py b/plinth/modules/sso/__init__.py index 8a3aeddb5..ed6e1a659 100644 --- a/plinth/modules/sso/__init__.py +++ b/plinth/modules/sso/__init__.py @@ -1,17 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Single Sign On services. -""" +"""FreedomBox app to configure Single Sign On services.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth.package import Packages +from . import privileged + class SSOApp(app_module.App): """FreedomBox app for single sign on.""" + app_id = 'sso' _version = 1 @@ -34,4 +34,4 @@ class SSOApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('auth-pubtkt', ['create-key-pair']) + privileged.create_key_pair() diff --git a/actions/auth-pubtkt b/plinth/modules/sso/privileged.py old mode 100755 new mode 100644 similarity index 50% rename from actions/auth-pubtkt rename to plinth/modules/sso/privileged.py index bdf7f8f9c..4b7f3212a --- a/actions/auth-pubtkt +++ b/plinth/modules/sso/privileged.py @@ -1,44 +1,23 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Module with utilities to generate a auth_pubtkt ticket and -sign it with the FreedomBox server's private key. +"""Generate a auth_pubtkt ticket. + +Sign tickets with the FreedomBox server's private key. """ -import argparse import base64 import datetime import os from OpenSSL import crypto +from plinth.actions import privileged + KEYS_DIRECTORY = '/etc/apache2/auth-pubtkt-keys' -def parse_arguments(): - """ Return parsed command line arguments as dictionary. """ - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser( - 'create-key-pair', help='create a key pair for the apache server ' - 'to sign auth_pubtkt tickets') - gen_tkt = subparsers.add_parser('generate-ticket', - help='generate auth_pubtkt ticket') - gen_tkt.add_argument('--uid', help='username of the user') - gen_tkt.add_argument('--private-key-file', - help='path of the private key file of the server') - gen_tkt.add_argument('--tokens', - help='tokens, usually containing the user groups') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_create_key_pair(_): - """Create public/private key pair for signing the auth_pubtkt - tickets. - """ +@privileged +def create_key_pair(): + """Create public/private key pair for signing the tickets.""" private_key_file = os.path.join(KEYS_DIRECTORY, 'privkey.pem') public_key_file = os.path.join(KEYS_DIRECTORY, 'pubkey.pem') @@ -64,9 +43,10 @@ def subcommand_create_key_pair(_): os.chmod(fil, 0o440) -def create_ticket(pkey, uid, validuntil, ip=None, tokens=None, udata=None, - graceperiod=None, extra_fields=None): +def _create_ticket(pkey, uid, validuntil, ip=None, tokens=None, udata=None, + graceperiod=None, extra_fields=None): """Create and return a signed mod_auth_pubtkt ticket.""" + tokens = ','.join(tokens) fields = [ f'uid={uid}', f'validuntil={int(validuntil)}', @@ -78,49 +58,33 @@ def create_ticket(pkey, uid, validuntil, ip=None, tokens=None, udata=None, and ';'.join(['{}={}'.format(k, v) for k, v in extra_fields]), ] data = ';'.join(filter(None, fields)) - signature = 'sig={}'.format(sign(pkey, data)) + signature = 'sig={}'.format(_sign(pkey, data)) return ';'.join([data, signature]) -def sign(pkey, data): - """Calculates and returns ticket's signature.""" +def _sign(pkey, data): + """Calculate and return ticket's signature.""" sig = crypto.sign(pkey, data.encode(), 'sha512') return base64.b64encode(sig).decode() -def subcommand_generate_ticket(arguments): +@privileged +def generate_ticket(uid: str, private_key_file: str, tokens: list[str]) -> str: """Generate a mod_auth_pubtkt ticket using login credentials.""" - uid = arguments.uid - private_key_file = arguments.private_key_file - tokens = arguments.tokens with open(private_key_file, 'r', encoding='utf-8') as fil: 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)) + valid_until = _minutes_from_now(12 * 60) + grace_period = _minutes_from_now(11 * 60) + return _create_ticket(pkey, uid, valid_until, tokens=tokens, + graceperiod=grace_period) -def minutes_from_now(minutes): +def _minutes_from_now(minutes): """Return a timestamp at the given number of minutes from now.""" - return seconds_from_now(minutes * 60) + return _seconds_from_now(minutes * 60) -def seconds_from_now(seconds): +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() - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/sso/tests/test_actions.py b/plinth/modules/sso/tests/test_privileged.py similarity index 58% rename from plinth/modules/sso/tests/test_actions.py rename to plinth/modules/sso/tests/test_privileged.py index 147015a04..6b57168ba 100644 --- a/plinth/modules/sso/tests/test_actions.py +++ b/plinth/modules/sso/tests/test_privileged.py @@ -7,34 +7,33 @@ import os import pytest +from plinth.modules.sso import privileged from plinth.modules.sso.views import PRIVATE_KEY_FILE_NAME -actions_name = 'auth-pubtkt' +pytestmark = pytest.mark.usefixtures('mock_privileged') +privileged_modules_to_mock = ['plinth.modules.sso.privileged'] @pytest.fixture(autouse=True) -def fixture_keys_directory(actions_module, tmpdir): +def fixture_keys_directory(tmpdir): """Set keys directory in the actions module.""" - actions_module.KEYS_DIRECTORY = str(tmpdir) + privileged.KEYS_DIRECTORY = str(tmpdir) @pytest.fixture(name='existing_key_pair') -def fixture_existing_key_pair(call_action): +def fixture_existing_key_pair(): """A fixture to create key pair if needed.""" - call_action(['create-key-pair']) + privileged.create_key_pair() -def test_generate_ticket(call_action, existing_key_pair, actions_module): +def test_generate_ticket(existing_key_pair): """Test generating a ticket.""" username = 'tester' - groups = 'freedombox-share,syncthing,web-search' + groups = ['freedombox-share', 'syncthing', 'web-search'] - private_key_file = os.path.join(actions_module.KEYS_DIRECTORY, + private_key_file = os.path.join(privileged.KEYS_DIRECTORY, PRIVATE_KEY_FILE_NAME) - ticket = call_action([ - 'generate-ticket', '--uid', username, '--private-key-file', - private_key_file, '--tokens', groups - ]) + ticket = privileged.generate_ticket(username, private_key_file, groups) fields = {} for item in ticket.split(';'): @@ -47,5 +46,5 @@ def test_generate_ticket(call_action, existing_key_pair, actions_module): assert fields['uid'] == username assert int(fields['validuntil']) > 0 - assert fields['tokens'] == groups + assert fields['tokens'] == ','.join(groups) assert int(fields['graceperiod']) > 0 diff --git a/plinth/modules/sso/views.py b/plinth/modules/sso/views.py index 083d3eea7..006072aa9 100644 --- a/plinth/modules/sso/views.py +++ b/plinth/modules/sso/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for the Single Sign On app of FreedomBox. -""" +"""Views for the Single Sign On app of FreedomBox.""" import logging import os @@ -17,8 +15,9 @@ from django.contrib.auth.views import LoginView from django.http import HttpResponseRedirect from django.utils.translation import gettext as _ -from plinth import actions, translation, utils, web_framework +from plinth import translation, utils, web_framework +from . import privileged from .forms import AuthenticationForm, CaptchaAuthenticationForm PRIVATE_KEY_FILE_NAME = 'privkey.pem' @@ -29,15 +28,11 @@ logger = logging.getLogger(__name__) def set_ticket_cookie(user, response): - """Generate and set a mod_auth_pubtkt as a cookie in the provided - response. - """ + """Generate and set a mod_auth_pubtkt as a cookie in the response.""" tokens = list(map(lambda g: g.name, user.groups.all())) private_key_file = os.path.join(KEYS_DIRECTORY, PRIVATE_KEY_FILE_NAME) - ticket = actions.superuser_run('auth-pubtkt', [ - 'generate-ticket', '--uid', user.username, '--private-key-file', - private_key_file, '--tokens', ','.join(tokens) - ]) + ticket = privileged.generate_ticket(user.username, private_key_file, + tokens) response.set_cookie(SSO_COOKIE_NAME, urllib.parse.quote(ticket)) return response @@ -46,13 +41,14 @@ class SSOLoginView(LoginView): """View to login to FreedomBox and set a auth_pubtkt cookie. Cookie will be used to provide Single Sign On for some other applications. - """ + redirect_authenticated_user = True template_name = 'login.html' form_class = AuthenticationForm def dispatch(self, request, *args, **kwargs): + """Handle a request and return a HTTP response.""" response = super().dispatch(request, *args, **kwargs) if request.user.is_authenticated: translation.set_language(request, response, @@ -65,15 +61,19 @@ class SSOLoginView(LoginView): # axes_form_invalid when axes >= 5.0.0 becomes available in Debian stable. @axes_form_invalid def form_invalid(self, *args, **kwargs): + """Trigger django-axes logic to deal with too many attempts.""" return super().form_invalid(*args, **kwargs) class CaptchaLoginView(LoginView): + """A login view with mandatory CAPTCHA image.""" + redirect_authenticated_user = True template_name = 'login.html' form_class = CaptchaAuthenticationForm def dispatch(self, request, *args, **kwargs): + """Handle a request and return a HTTP response.""" response = super().dispatch(request, *args, **kwargs) if not request.POST: return response @@ -102,7 +102,7 @@ def logout(request): def refresh(request): - """Simulate cookie refresh - redirect logged in user with a new cookie""" + """Simulate cookie refresh - redirect logged in user with a new cookie.""" redirect_url = request.GET.get(REDIRECT_FIELD_NAME, '') response = HttpResponseRedirect(redirect_url) response.delete_cookie(SSO_COOKIE_NAME) diff --git a/plinth/modules/storage/__init__.py b/plinth/modules/storage/__init__.py index a823ccba6..7b29265e6 100644 --- a/plinth/modules/storage/__init__.py +++ b/plinth/modules/storage/__init__.py @@ -1,25 +1,21 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to manage storage. -""" +"""FreedomBox app to manage storage.""" import base64 import logging -import subprocess import psutil from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_noop -from plinth import actions from plinth import app as app_module from plinth import cfg, glib, menu -from plinth.errors import ActionError, PlinthError +from plinth.errors import PlinthError from plinth.modules.backups.components import BackupRestore from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest, udisks2 +from . import manifest, privileged, udisks2 _description = [ format_lazy( @@ -77,19 +73,19 @@ class StorageApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('storage', ['setup']) + privileged.setup() self.enable() disks = get_disks() root_device = get_root_device(disks) if is_expandable(root_device): try: - expand_partition(root_device) - except ActionError: + privileged.expand_partition(root_device) + except Exception: pass def get_disks(): - """Returns list of disks and their free space. + """Return list of disks and their free space. The primary source of information is UDisks' list of block devices. Information from df is used for free space available. @@ -136,8 +132,8 @@ def get_mounts(): def _get_disks_from_df(): """Return the list of disks and free space available using 'df'.""" try: - output = actions.superuser_run('storage', ['usage-info']) - except subprocess.CalledProcessError as exception: + output = privileged.usage_info() + except Exception as exception: logger.exception('Error getting disk information: %s', exception) return [] @@ -162,7 +158,7 @@ def _get_disks_from_df(): def get_filesystem_type(mount_point='/'): - """Returns the type of the filesystem mounted at mountpoint.""" + """Return the type of the filesystem mounted at mountpoint.""" for partition in psutil.disk_partitions(): if partition.mountpoint == mount_point: return partition.fstype @@ -204,19 +200,10 @@ def is_expandable(device): return False try: - output = actions.superuser_run('storage', - ['is-partition-expandable', device], - log_error=False) - except actions.ActionError: + return privileged.is_partition_expandable(device, _log_error=False) + except Exception: return False - return int(output.strip()) - - -def expand_partition(device): - """Expand a partition.""" - actions.superuser_run('storage', ['expand-partition', device]) - def format_bytes(size): """Return human readable disk size from bytes.""" diff --git a/plinth/modules/storage/forms.py b/plinth/modules/storage/forms.py index 3b7cab766..232cdc9bb 100644 --- a/plinth/modules/storage/forms.py +++ b/plinth/modules/storage/forms.py @@ -1,26 +1,24 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Forms for directory selection. -""" +"""Forms for directory selection.""" -import json import os from django import forms from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth.modules import storage +from plinth.modules.samba import privileged as samba_privileged + +from . import privileged def get_available_samba_shares(): """Get available samba shares.""" available_shares = [] if _is_app_enabled('samba'): - samba_shares = json.loads( - actions.superuser_run('samba', ['get-shares'])) + samba_shares = samba_privileged.get_shares() if samba_shares: disks = storage.get_mounts() for share in samba_shares: @@ -41,6 +39,8 @@ def _is_app_enabled(app_id): class DirectoryValidator: + """Validation helper to check a directory.""" + username = None check_writable = False check_creatable = False @@ -49,6 +49,7 @@ class DirectoryValidator: def __init__(self, username=None, check_writable=None, check_creatable=None): + """Initialize the validator.""" if username is not None: self.username = username if check_writable is not None: @@ -61,29 +62,22 @@ class DirectoryValidator: if not value.startswith('/'): raise ValidationError(_('Invalid directory name.'), 'invalid') - command = ['validate-directory', '--path', value] - if self.check_creatable: - command.append('--check-creatable') - elif self.check_writable: - command.append('--check-writable') + try: + if not self.username: + raise ValueError('Invalid username for directory validator') - if self.username: - output = actions.run_as_user('storage', command, - become_user=self.username) - else: - output = actions.run('storage', command) - - if 'ValidationError' in output: - error_nr = int(output.strip().split()[1]) - if error_nr == 1: - raise ValidationError(_('Directory does not exist.'), - 'invalid') - elif error_nr == 2: - raise ValidationError(_('Path is not a directory.'), 'invalid') - elif error_nr == 3: + privileged.validate_directory(value, self.check_creatable, + self.check_writable, + _run_as_user=self.username) + except FileNotFoundError: + raise ValidationError(_('Directory does not exist.'), 'invalid') + except NotADirectoryError: + raise ValidationError(_('Path is not a directory.'), 'invalid') + except PermissionError as exception: + if exception.args[0] == 'read': raise ValidationError( _('Directory is not readable by the user.'), 'invalid') - elif error_nr == 4: + else: raise ValidationError( _('Directory is not writable by the user.'), 'invalid') diff --git a/actions/storage b/plinth/modules/storage/privileged.py old mode 100755 new mode 100644 similarity index 66% rename from actions/storage rename to plinth/modules/storage/privileged.py index ec682ec17..9138a7373 --- a/actions/storage +++ b/plinth/modules/storage/privileged.py @@ -1,85 +1,31 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for disks manager. -""" +"""Configure disks manager.""" -import argparse -import json import os import re import stat import subprocess -import sys from plinth import utils +from plinth.actions import privileged -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Configure storage after install') - - subparser = subparsers.add_parser( - 'is-partition-expandable', - help='Return whether a given partition can be expanded') - subparser.add_argument( - 'device', help='Partition for which check needs to be performed') - - subparser = subparsers.add_parser( - 'expand-partition', - help='Expand a partition to take adjacent free space') - subparser.add_argument('device', - help='Partition which needs to be resized') - subparser.add_argument( - '--mount-point', default='/', - help=('Mount point which the device is mounted. ' - 'Needed for btrfs filesystems')) - - subparser = subparsers.add_parser('mount', help='Mount a filesystem') - subparser.add_argument('--block-device', - help='Block device of the filesystem to mount') - - subparser = subparsers.add_parser('eject', help='Eject a storage device') - subparser.add_argument('device', help='Path of the device to eject') - - subparsers.add_parser('usage-info', - help='Get information about disk space usage') - - subparser = subparsers.add_parser('validate-directory', - help='Validate a directory') - subparser.add_argument('--path', help='Path of the directory', - required=True) - subparser.add_argument('--check-creatable', required=False, default=False, - action='store_true', - help='Check that the directory is creatable') - subparser.add_argument('--check-writable', required=False, default=False, - action='store_true', - help='Check that the directory is writable') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_is_partition_expandable(arguments): +@privileged +def is_partition_expandable(device: str) -> int: """Return a list of partitions that can be expanded.""" - _, _, free_space = _get_free_space(arguments.device) - print(free_space['size']) + _, _, free_space = _get_free_space(device) + return int(free_space['size']) -def subcommand_expand_partition(arguments): +@privileged +def expand_partition(device: str, mount_point: str = '/'): """Expand a partition to take adjacent free space.""" - device = arguments.device - mount_point = arguments.mount_point device, requested_partition, free_space = _get_free_space(device) if requested_partition['table_type'] == 'msdos' and \ int(requested_partition['number']) >= 5: - print('Expanding logical partitions currently unsupported', - file=sys.stderr) - sys.exit(4) + raise RuntimeError( + 'Expanding logical partitions currently unsupported') if requested_partition['table_type'] == 'gpt': _move_gpt_second_header(device) @@ -102,8 +48,7 @@ def _move_gpt_second_header(device): try: subprocess.run(command, check=True) except subprocess.CalledProcessError: - print('Error moving GPT second header to the end') - sys.exit(6) + raise RuntimeError('Error moving GPT second header to the end') def _resize_partition(device, requested_partition, free_space): @@ -127,8 +72,7 @@ def _resize_partition(device, requested_partition, free_space): subprocess.run(fallback_command, check=True, input=input_text.encode()) except subprocess.CalledProcessError as exception: - print('Error expanding partition:', exception, file=sys.stderr) - sys.exit(5) + raise RuntimeError(f'Error expanding partition: {exception}') def _resize_file_system(device, requested_partition, free_space, @@ -149,8 +93,7 @@ def _resize_ext4(device, requested_partition, _free_space, _mount_point): subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) except subprocess.CalledProcessError as exception: - print('Error expanding filesystem:', exception, file=sys.stderr) - sys.exit(6) + raise RuntimeError(f'Error expanding filesystem: {exception}') def _resize_btrfs(_device, _requested_partition, _free_space, mount_point='/'): @@ -159,8 +102,7 @@ def _resize_btrfs(_device, _requested_partition, _free_space, mount_point='/'): command = ['btrfs', 'filesystem', 'resize', 'max', mount_point] subprocess.run(command, stdout=subprocess.DEVNULL, check=True) except subprocess.CalledProcessError as exception: - print('Error expanding filesystem:', exception, file=sys.stderr) - sys.exit(6) + raise RuntimeError(f'Error expanding filesystem: {exception}') def _get_free_space(device): @@ -172,21 +114,18 @@ def _get_free_space(device): requested_partition, free_spaces = \ _get_partitions_and_free_spaces(device, partition_number) except Exception as exception: - print('Error getting partition details: ', exception, file=sys.stderr) - sys.exit(2) + raise RuntimeError(f'Error getting partition details: {exception}') # Don't accept extended partitions for now if requested_partition['table_type'] == 'msdos' and \ int(requested_partition['number']) >= 5: - print('Expanding logical partitions currently unsupported', - file=sys.stderr) - sys.exit(3) + raise RuntimeError( + 'Expanding logical partitions currently unsupported') # Don't accept anything but btrfs and ext4 filesystems if requested_partition['type'] not in ('btrfs', 'ext4'): - print('Unsupported file system type: ', requested_partition['type'], - file=sys.stderr) - sys.exit(4) + raise RuntimeError( + f'Unsupported file system type: {requested_partition["type"]}') found_free_space = None for free_space in free_spaces: @@ -199,7 +138,7 @@ def _get_free_space(device): found_free_space = free_space if not found_free_space: - sys.exit(5) + raise RuntimeError('No free space available') return device, requested_partition, found_free_space @@ -218,8 +157,7 @@ def _get_root_device_and_partition_number(device): if not match: match = re.match(r'(.+[a-zA-Z])(\d+)$', device) if not match: - print('Invalid device, must be a partition', file=sys.stderr) - sys.exit(1) + raise ValueError('Invalid device, must be a partition') return match.group(1), match.group(2) @@ -263,7 +201,8 @@ def _interpret_unit(value): return int(value) -def subcommand_mount(arguments): +@privileged +def mount(block_device: str): """Mount a disk are root user. XXX: This is primarily to provide compatibility with older code that used @@ -276,22 +215,16 @@ def subcommand_mount(arguments): UDISKS_FILESYSTEM_SHARED=1 by writing a udev rule. """ - process = subprocess.run([ - 'udisksctl', 'mount', '--block-device', arguments.block_device, + subprocess.run([ + 'udisksctl', 'mount', '--block-device', block_device, '--no-user-interaction' - ], check=False) - sys.exit(process.returncode) + ], check=True) -def subcommand_eject(arguments): +@privileged +def eject(device_path: str) -> str: """Eject a device by its path.""" - device_path = arguments.device - try: - drive = eject_drive_of_device(device_path) - print(json.dumps(drive)) - except Exception as exception: - print(exception, file=sys.stderr) - sys.exit(1) + return _eject_drive_of_device(device_path) def _get_options(): @@ -302,7 +235,7 @@ def _get_options(): return options -def eject_drive_of_device(device_path): +def _eject_drive_of_device(device_path): """Eject a device after unmounting all of its partitions. Return the details (model, vendor) of drives ejected. @@ -327,10 +260,10 @@ def eject_drive_of_device(device_path): block_device = obj.get_block() drive_object_path = block_device.props.drive if drive_object_path != '/': - umount_all_filesystems_of_drive(drive_object_path) + _umount_all_filesystems_of_drive(drive_object_path) else: # Block device has not associated drive - umount_filesystem(obj.get_filesystem()) + _umount_filesystem(obj.get_filesystem()) # Eject the drive drive = client.get_drive_for_block(block_device) @@ -350,13 +283,13 @@ def eject_drive_of_device(device_path): return None -def umount_filesystem(filesystem): - """Unmount a filesystem """ +def _umount_filesystem(filesystem): + """Unmount a filesystem.""" if filesystem and filesystem.props.mount_points: filesystem.call_unmount_sync(_get_options()) -def umount_all_filesystems_of_drive(drive_object_path): +def _umount_all_filesystems_of_drive(drive_object_path): """Unmount all filesystems on block devices of a drive.""" udisks = utils.import_from_gi('UDisks', '2.0') client = udisks.Client.new_sync() @@ -367,10 +300,11 @@ def umount_all_filesystems_of_drive(drive_object_path): if not block_device or block_device.props.drive != drive_object_path: continue - umount_filesystem(obj.get_filesystem()) + _umount_filesystem(obj.get_filesystem()) -def subcommand_setup(_): +@privileged +def setup(): """Configure storage.""" # create udisks2 default mount directory mounts_directory = '/media/root' @@ -384,58 +318,43 @@ def subcommand_setup(_): os.chmod(mounts_directory, stats.st_mode | stat.S_IROTH | stat.S_IXOTH) -def subcommand_usage_info(_): +@privileged +def usage_info() -> str: """Get information about disk space usage.""" command = [ 'df', '--exclude-type=tmpfs', '--exclude-type=devtmpfs', '--block-size=1', '--output=source,fstype,size,used,avail,pcent,target' ] - subprocess.run(command, check=True) + return subprocess.check_output(command).decode() -def subcommand_validate_directory(arguments): - """Validate a directory""" +@privileged +def validate_directory(directory: str, check_creatable: bool, + check_writable: bool): + """Validate a directory.""" if os.geteuid() == 0: raise RuntimeError('You must not be root to run this command') - directory = arguments.path - def part_exists(path): - """Returns part of the path that exists.""" + """Return part of the path that exists.""" if not path or os.path.exists(path): return path return part_exists(os.path.dirname(path)) - if arguments.check_creatable: + if check_creatable: directory = part_exists(directory) if not directory: directory = '.' else: if not os.path.exists(directory): - # doesn't exist - print('ValidationError: 1') - return + raise FileNotFoundError if not os.path.isdir(directory): - # is not a directory - print('ValidationError: 2') - elif not os.access(directory, os.R_OK): - # is not readable - print('ValidationError: 3') - elif arguments.check_writable or arguments.check_creatable: + raise NotADirectoryError + + if not os.access(directory, os.R_OK): + raise PermissionError('read') + + if check_writable or check_creatable: if not os.access(directory, os.W_OK): - # is not writable - print('ValidationError: 4') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() + raise PermissionError('write') diff --git a/plinth/modules/storage/tests/test_storage.py b/plinth/modules/storage/tests/test_storage.py index 4877ee81b..cb2672bd4 100644 --- a/plinth/modules/storage/tests/test_storage.py +++ b/plinth/modules/storage/tests/test_storage.py @@ -4,14 +4,17 @@ Test module for storage module operations. """ import contextlib -import os -import pathlib import re import subprocess import tempfile import pytest +from plinth.modules.storage import privileged + +pytestmark = pytest.mark.usefixtures('mock_privileged') +privileged_modules_to_mock = ['plinth.modules.storage.privileged'] + class Disk(): """Context manager to create/destroy a disk.""" @@ -255,8 +258,11 @@ def test_ext4_expansion(partition_table_type): def _assert_free_space(disk, partition_number, space=True): """Verify that free is available/not available after a partition.""" device = disk.get_partition_device(partition_number) - result = _check_action(['storage', 'is-partition-expandable', device]) - assert result == space + if space: + privileged.is_partition_expandable(device) + else: + with pytest.raises(RuntimeError): + privileged.is_partition_expandable(device) def _expand_partition(disk, partition_number, success=True): @@ -264,34 +270,15 @@ def _expand_partition(disk, partition_number, success=True): _assert_aligned(disk, partition_number) with disk.mount_partition(partition_number) as mount_point: device = disk.get_partition_device(partition_number) - result = _check_action([ - 'storage', 'expand-partition', device, '--mount-point', mount_point - ]) + if success: + privileged.expand_partition(device, mount_point) + else: + with pytest.raises(RuntimeError): + privileged.expand_partition(device, mount_point) - assert result == success _assert_aligned(disk, partition_number) -def _call_action(action_command, check=True, **kwargs): - """Call the action script.""" - test_directory = pathlib.Path(__file__).parent - top_directory = (test_directory / '..' / '..' / '..' / '..').resolve() - action_command[0] = top_directory / 'actions' / action_command[0] - kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL) - kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL) - env = dict(os.environ, PYTHONPATH=str(top_directory)) - return subprocess.run(action_command, env=env, check=check, **kwargs) - - -def _check_action(action_command): - """Return success/failure result of the action command.""" - try: - _call_action(action_command) - return True - except subprocess.CalledProcessError: - return False - - def _assert_aligned(disk, partition_number): """Test that partition is optimally aligned.""" subprocess.run([ @@ -319,43 +306,40 @@ def _assert_ext4_file_system_healthy(disk, partition_number): def _assert_validate_directory(path, error, check_writable=False, check_creatable=False): """Perform directory validation checks.""" - action_command = ['storage', 'validate-directory', '--path', path] - if check_writable: - action_command += ['--check-writable'] - if check_creatable: - action_command += ['--check-creatable'] - proc = _call_action(action_command, stderr=subprocess.PIPE, - stdout=subprocess.PIPE) - output = proc.stdout.decode() - if 'ValidationError' in output: - error_nr = output.strip().split()[1] - assert error_nr == error + if error: + match = None if not error.args else error.args[0] + with pytest.raises(error.__class__, match=match): + privileged.validate_directory(path, check_creatable, + check_writable) else: - assert output == error + privileged.validate_directory(path, check_creatable, check_writable) @pytest.mark.usefixtures('needs_not_root') -@pytest.mark.parametrize('path,error', [('/missing', '1'), - ('/etc/os-release', '2'), - ('/root', '3'), ('/', ''), - ('/etc/..', '')]) +@pytest.mark.parametrize('path,error', + [('/missing', FileNotFoundError()), + ('/etc/os-release', NotADirectoryError()), + ('/root', PermissionError('read')), ('/', None), + ('/etc/..', None)]) def test_validate_directory(path, error): """Test that directory validation returns expected output.""" _assert_validate_directory(path, error) @pytest.mark.usefixtures('needs_not_root') -@pytest.mark.parametrize('path,error', [('/', '4'), ('/tmp', '')]) +@pytest.mark.parametrize('path,error', [('/', PermissionError('write')), + ('/tmp', None)]) def test_validate_directory_writable(path, error): """Test that directory writable validation returns expected output.""" _assert_validate_directory(path, error, check_writable=True) @pytest.mark.usefixtures('needs_not_root') -@pytest.mark.parametrize('path,error', - [('/var/lib/plinth_storage_test_not_exists', '4'), - ('/tmp/plint_storage_test_not_exists', ''), - ('/var/../tmp/plint_storage_test_not_exists', '')]) +@pytest.mark.parametrize( + 'path,error', + [('/var/lib/plinth_storage_test_not_exists', PermissionError('write')), + ('/tmp/plint_storage_test_not_exists', None), + ('/var/../tmp/plint_storage_test_not_exists', None)]) def test_validate_directory_creatable(path, error): """Test that directory creatable validation returns expected output.""" _assert_validate_directory(path, error, check_creatable=True) diff --git a/plinth/modules/storage/udisks2.py b/plinth/modules/storage/udisks2.py index a98d985c8..9b536b40e 100644 --- a/plinth/modules/storage/udisks2.py +++ b/plinth/modules/storage/udisks2.py @@ -1,15 +1,14 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Handle disk operations using UDisk2 DBus API. -""" +"""Handle disk operations using UDisk2 DBus API.""" import logging import threading -from plinth import actions, cfg -from plinth.errors import ActionError +from plinth import cfg from plinth.utils import import_from_gi +from . import privileged + glib = import_from_gi('GLib', '2.0') gio = import_from_gi('Gio', '2.0') @@ -195,11 +194,8 @@ def _mount(object_path): logger.info('Auto-mounting device: %s %s', block_device.id, block_device.preferred_device) try: - actions.superuser_run( - 'storage', - ['mount', '--block-device', block_device.preferred_device], - log_error=False) - except ActionError as exception: + privileged.mount(block_device.preferred_device, _log_error=False) + except Exception as exception: parts = exception.args[2].split(':') if parts[1].strip() != 'GDBus.Error': raise diff --git a/plinth/modules/storage/views.py b/plinth/modules/storage/views.py index 749c27e8d..851929cb7 100644 --- a/plinth/modules/storage/views.py +++ b/plinth/modules/storage/views.py @@ -1,9 +1,6 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Views for storage module. -""" +"""Views for storage module.""" -import json import logging import urllib.parse @@ -14,17 +11,17 @@ from django.urls import reverse from django.utils.translation import gettext as _ from django.views.decorators.http import require_POST -from plinth import actions, views -from plinth.errors import ActionError +from plinth import views from plinth.modules import storage -from . import get_error_message +from . import get_error_message, privileged logger = logging.getLogger(__name__) class StorageAppView(views.AppView): """Show storage information.""" + app_id = 'storage' template_name = 'storage.html' @@ -63,7 +60,7 @@ def expand(request): def expand_partition(request, device): """Expand the partition.""" try: - storage.expand_partition(device) + privileged.expand_partition(device) except Exception as exception: messages.error( request, @@ -83,8 +80,7 @@ def eject(request, device_path): device_path = urllib.parse.unquote(device_path) try: - drive = json.loads( - actions.superuser_run('storage', ['eject', device_path])) + drive = privileged.eject(device_path) if drive: messages.success( request, @@ -93,8 +89,8 @@ def eject(request, device_path): drive_model=drive['model'])) else: messages.success(request, _('Device can be safely unplugged.')) - except ActionError as exception: - message = get_error_message(exception.args[2]) + except Exception as exception: + message = get_error_message(exception.args[-2].decode()) # stdout logger.error('Error ejecting device - %s', message) messages.error( diff --git a/plinth/modules/syncthing/__init__.py b/plinth/modules/syncthing/__init__.py index 2f0a9eb88..fb1d53a64 100644 --- a/plinth/modules/syncthing/__init__.py +++ b/plinth/modules/syncthing/__init__.py @@ -1,11 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Syncthing. -""" +"""FreedomBox app to configure Syncthing.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -13,11 +10,12 @@ from plinth.modules.apache.components import Webserver from plinth.modules.backups.components import BackupRestore from plinth.modules.firewall.components import Firewall from plinth.modules.users import add_user_to_share_group +from plinth.modules.users import privileged as users_privileged from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('Syncthing is an application to synchronize files across multiple ' @@ -106,13 +104,13 @@ class SyncthingApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('syncthing', ['setup']) + privileged.setup() add_user_to_share_group(SYSTEM_USER, SyncthingApp.DAEMON) if not old_version: self.enable() - actions.superuser_run('syncthing', ['setup-config']) + privileged.setup_config() if old_version == 1 and self.is_enabled(): self.get_component('firewall-syncthing-ports').enable() @@ -122,9 +120,7 @@ class SyncthingApp(app_module.App): old_groupname = 'syncthing' new_groupname = 'syncthing-access' - actions.superuser_run( - 'users', - options=['rename-group', old_groupname, new_groupname]) + users_privileged.rename_group(old_groupname, new_groupname) from django.contrib.auth.models import Group Group.objects.filter(name=old_groupname).update(name=new_groupname) diff --git a/actions/syncthing b/plinth/modules/syncthing/privileged.py old mode 100755 new mode 100644 similarity index 70% rename from actions/syncthing rename to plinth/modules/syncthing/privileged.py index 200dbb117..efa8c40f7 --- a/actions/syncthing +++ b/plinth/modules/syncthing/privileged.py @@ -1,10 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Syncthing. -""" +"""Configure Syncthing.""" -import argparse import grp import os import pwd @@ -15,24 +11,12 @@ import time import augeas from plinth import action_utils +from plinth.actions import privileged DATA_DIR = '/var/lib/syncthing' CONF_FILE = DATA_DIR + '/.config/syncthing/config.xml' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', help='Setup Syncthing') - - subparsers.add_parser('setup-config', help='Setup Syncthing configuration') - - subparsers.required = True - return parser.parse_args() - - def augeas_load(): """Initialize Augeas.""" aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + @@ -42,8 +26,9 @@ def augeas_load(): return aug -def subcommand_setup(_): - """Actions to be performed before installing Syncthing""" +@privileged +def setup(): + """Perform post-install actions for Syncthing.""" # Create syncthing group if needed. try: grp.getgrnam('syncthing') @@ -65,7 +50,8 @@ def subcommand_setup(_): shutil.chown(DATA_DIR, user='syncthing', group='syncthing') -def subcommand_setup_config(_): +@privileged +def setup_config(): """Make configuration changes.""" # wait until the configuration file is created by the syncthing daemon timeout = 300 @@ -94,16 +80,3 @@ def subcommand_setup_config(_): if conf_changed: action_utils.service_try_restart('syncthing@syncthing') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/tor/__init__.py b/plinth/modules/tor/__init__.py index 279f7f8c7..cae907cde 100644 --- a/plinth/modules/tor/__init__.py +++ b/plinth/modules/tor/__init__.py @@ -1,13 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Tor. -""" - -import json +"""FreedomBox app to configure Tor.""" from django.utils.translation import gettext_lazy as _ -from plinth import action_utils, actions +from plinth import action_utils from plinth import app as app_module from plinth import cfg, menu from plinth.daemon import (Daemon, app_is_running, diagnose_netcat, @@ -21,7 +17,7 @@ from plinth.package import Packages from plinth.signals import domain_added, domain_removed from plinth.utils import format_lazy -from . import manifest, utils +from . import manifest, privileged, utils _description = [ _('Tor is an anonymous communication system. You can learn more ' @@ -109,13 +105,12 @@ class TorApp(app_module.App): def enable(self): """Enable the app and update firewall ports.""" super().enable() - actions.superuser_run('tor', ['update-ports']) + privileged.update_ports() update_hidden_service_domain() def disable(self): """Disable APT use of Tor before disabling.""" - actions.superuser_run('tor', - ['configure', '--apt-transport-tor', 'disable']) + privileged.configure(apt_transport_tor=False) super().disable() update_hidden_service_domain() @@ -125,8 +120,8 @@ class TorApp(app_module.App): results.extend(_diagnose_control_port()) - output = actions.superuser_run('tor', ['get-status']) - ports = json.loads(output)['ports'] + status = privileged.get_status() + ports = status['ports'] results.append([ _('Tor relay port available'), @@ -169,12 +164,9 @@ class TorApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('tor', - ['setup', '--old-version', - str(old_version)]) + privileged.setup(old_version) if not old_version: - actions.superuser_run( - 'tor', ['configure', '--apt-transport-tor', 'enable']) + privileged.configure(apt_transport_tor=True) update_hidden_service_domain() self.enable() diff --git a/actions/tor b/plinth/modules/tor/privileged.py old mode 100755 new mode 100644 similarity index 76% rename from actions/tor rename to plinth/modules/tor/privileged.py index 6189562f9..75b572001 --- a/actions/tor +++ b/plinth/modules/tor/privileged.py @@ -1,21 +1,18 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for the Tor service -""" +"""Configure Tor service.""" -import argparse import codecs -import json import os import re import socket import subprocess import time +from typing import Any, Optional, Union import augeas from plinth import action_utils +from plinth.actions import privileged from plinth.modules.tor.utils import (APT_TOR_PREFIX, get_augeas, get_real_apt_uri_path, iter_apt_uris) @@ -25,48 +22,10 @@ TOR_STATE_FILE = '/var/lib/tor-instances/plinth/state' TOR_AUTH_COOKIE = '/var/run/tor-instances/plinth/control.authcookie' -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - setup_parser = subparsers.add_parser('setup', - help='Setup Tor configuration') - setup_parser.add_argument( - '--old-version', type=int, required=True, - help='Version number being upgraded from or None if setting up first ' - 'time.') - - subparsers.add_parser('get-status', help='Get Tor status in JSON format') - - configure = subparsers.add_parser('configure', help='Configure Tor') - configure.add_argument('--relay', choices=['enable', 'disable'], - help='Configure relay') - configure.add_argument('--bridge-relay', choices=['enable', 'disable'], - help='Configure bridge relay') - configure.add_argument('--hidden-service', choices=['enable', 'disable'], - help='Configure hidden service') - configure.add_argument('--apt-transport-tor', - choices=['enable', 'disable'], - help='Configure package download over Tor') - configure.add_argument('--use-upstream-bridges', - choices=['enable', 'disable'], - help='Configure use of upstream bridges') - configure.add_argument('--upstream-bridges', - help='Set list of upstream bridges to use') - - subparsers.add_parser('update-ports', - help='Update firewall ports based on what Tor uses') - - subparsers.add_parser('restart', help='Restart Tor') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_setup(arguments): +@privileged +def setup(old_version: int): """Setup Tor configuration after installing it.""" - if arguments.old_version and arguments.old_version <= 4: + if old_version and old_version <= 4: _upgrade_orport_value() return @@ -98,7 +57,7 @@ def _first_time_setup(): aug.set(TOR_CONFIG + '/SocksPort[1]', '[::]:9050') aug.set(TOR_CONFIG + '/SocksPort[2]', '0.0.0.0:9050') aug.set(TOR_CONFIG + '/ControlPort', '9051') - _enable_relay(relay='enable', bridge='enable', aug=aug) + _enable_relay(relay=True, bridge=True, aug=aug) aug.set(TOR_CONFIG + '/ExitPolicy[1]', 'reject *:*') aug.set(TOR_CONFIG + '/ExitPolicy[2]', 'reject6 *:*') @@ -163,43 +122,46 @@ def _upgrade_orport_value(): action_utils.service_restart('firewalld') -def subcommand_get_status(_): - """Get Tor status in JSON format.""" - print(json.dumps(get_status())) - - -def subcommand_configure(arguments): +@privileged +def configure(use_upstream_bridges: Optional[bool] = None, + upstream_bridges: Optional[str] = None, + relay: Optional[bool] = None, + bridge_relay: Optional[bool] = None, + hidden_service: Optional[bool] = None, + apt_transport_tor: Optional[bool] = None): """Configure Tor.""" aug = augeas_load() - _use_upstream_bridges(arguments.use_upstream_bridges, aug=aug) + _use_upstream_bridges(use_upstream_bridges, aug=aug) - if arguments.use_upstream_bridges == 'enable': - arguments.relay = 'disable' - arguments.bridge_relay = 'disable' + if use_upstream_bridges: + relay = False + bridge_relay = False - if arguments.upstream_bridges: - _set_upstream_bridges(arguments.upstream_bridges, aug=aug) + if upstream_bridges: + _set_upstream_bridges(upstream_bridges, aug=aug) - _enable_relay(arguments.relay, arguments.bridge_relay, aug=aug) + _enable_relay(relay, bridge_relay, aug=aug) - if arguments.hidden_service == 'enable': + if hidden_service: _enable_hs(aug=aug) - elif arguments.hidden_service == 'disable': + elif hidden_service is not None: _disable_hs(aug=aug) - if arguments.apt_transport_tor == 'enable': + if apt_transport_tor: _enable_apt_transport_tor() - elif arguments.apt_transport_tor == 'disable': + elif apt_transport_tor is not None: _disable_apt_transport_tor() -def subcommand_update_ports(_): +@privileged +def update_ports(): """Update firewall ports based on what Tor uses.""" _update_ports() -def subcommand_restart(_): +@privileged +def restart(): """Restart Tor.""" if (action_utils.service_is_enabled('tor@plinth', strict_check=True) and action_utils.service_is_running('tor@plinth')): @@ -216,7 +178,8 @@ def subcommand_restart(_): time.sleep(10) -def get_status(): +@privileged +def get_status() -> dict[str, Union[bool, str, dict[str, Any]]]: """Return dict with Tor status.""" aug = augeas_load() return { @@ -229,32 +192,32 @@ def get_status(): } -def _are_upstream_bridges_enabled(aug): +def _are_upstream_bridges_enabled(aug) -> bool: """Return whether upstream bridges are being used.""" use_bridges = aug.get(TOR_CONFIG + '/UseBridges') return use_bridges == '1' -def _get_upstream_bridges(aug): +def _get_upstream_bridges(aug) -> str: """Return upstream bridges separated by newlines.""" matches = aug.match(TOR_CONFIG + '/Bridge') bridges = [aug.get(match) for match in matches] return '\n'.join(bridges) -def _is_relay_enabled(aug): +def _is_relay_enabled(aug) -> bool: """Return whether a relay is enabled.""" orport = aug.get(TOR_CONFIG + '/ORPort[1]') return bool(orport) and orport != '0' -def _is_bridge_relay_enabled(aug): +def _is_bridge_relay_enabled(aug) -> bool: """Return whether bridge relay is enabled.""" bridge = aug.get(TOR_CONFIG + '/BridgeRelay') return bridge == '1' -def _get_ports(): +def _get_ports() -> dict[str, str]: """Return dict mapping port names to numbers.""" ports = {} try: @@ -275,7 +238,7 @@ def _get_ports(): return ports -def _get_orport(): +def _get_orport() -> str: """Return the ORPort by querying running instance.""" cookie = open(TOR_AUTH_COOKIE, 'rb').read() cookie = codecs.encode(cookie, 'hex').decode() @@ -296,8 +259,8 @@ QUIT return matches.group(1) -def _get_hidden_service(aug=None): - """Return a string with configured Tor hidden service information""" +def _get_hidden_service(aug=None) -> dict[str, Any]: + """Return a string with configured Tor hidden service information.""" hs_enabled = False hs_status = 'Ok' hs_hostname = None @@ -344,7 +307,8 @@ def _disable(): action_utils.service_disable('tor@plinth') -def _use_upstream_bridges(use_upstream_bridges=None, aug=None): +def _use_upstream_bridges(use_upstream_bridges: Optional[bool] = None, + aug=None): """Enable use of upstream bridges.""" if use_upstream_bridges is None: return @@ -352,9 +316,9 @@ def _use_upstream_bridges(use_upstream_bridges=None, aug=None): if not aug: aug = augeas_load() - if use_upstream_bridges == 'enable': + if use_upstream_bridges: aug.set(TOR_CONFIG + '/UseBridges', '1') - elif use_upstream_bridges == 'disable': + else: aug.set(TOR_CONFIG + '/UseBridges', '0') aug.save() @@ -383,7 +347,8 @@ def _set_upstream_bridges(upstream_bridges=None, aug=None): aug.save() -def _enable_relay(relay=None, bridge=None, aug=None): +def _enable_relay(relay: Optional[bool], bridge: Optional[bool], + aug: augeas.Augeas): """Enable Tor bridge relay.""" if relay is None and bridge is None: return @@ -393,18 +358,18 @@ def _enable_relay(relay=None, bridge=None, aug=None): use_upstream_bridges = _are_upstream_bridges_enabled(aug) - if relay == 'enable' and not use_upstream_bridges: + if relay and not use_upstream_bridges: aug.set(TOR_CONFIG + '/ORPort[1]', '9001') aug.set(TOR_CONFIG + '/ORPort[2]', '[::]:9001') - elif relay == 'disable': + elif relay is not None: aug.remove(TOR_CONFIG + '/ORPort') - if bridge == 'enable' and not use_upstream_bridges: + if bridge and not use_upstream_bridges: aug.set(TOR_CONFIG + '/BridgeRelay', '1') aug.set(TOR_CONFIG + '/ServerTransportPlugin', 'obfs3,obfs4 exec /usr/bin/obfs4proxy') aug.set(TOR_CONFIG + '/ExtORPort', 'auto') - elif bridge == 'disable': + elif bridge is not None: aug.remove(TOR_CONFIG + '/BridgeRelay') aug.remove(TOR_CONFIG + '/ServerTransportPlugin') aug.remove(TOR_CONFIG + '/ExtORPort') @@ -413,7 +378,7 @@ def _enable_relay(relay=None, bridge=None, aug=None): def _enable_hs(aug=None): - """Enable Tor hidden service""" + """Enable Tor hidden service.""" if not aug: aug = augeas_load() @@ -429,7 +394,7 @@ def _enable_hs(aug=None): def _disable_hs(aug=None): - """Disable Tor hidden service""" + """Disable Tor hidden service.""" if not aug: aug = augeas_load() @@ -443,13 +408,7 @@ def _disable_hs(aug=None): def _enable_apt_transport_tor(): """Enable package download over Tor.""" - try: - aug = get_augeas() - except Exception: - # If there was an error, don't proceed - print('Error: Unable to understand sources format.') - exit(1) - + aug = get_augeas() for uri_path in iter_apt_uris(aug): uri_path = get_real_apt_uri_path(aug, uri_path) uri = aug.get(uri_path) @@ -527,16 +486,3 @@ def augeas_load(): '/etc/tor/instances/plinth/torrc') aug.load() return aug - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/tor/utils.py b/plinth/modules/tor/utils.py index 935e48a85..8dba7d8da 100644 --- a/plinth/modules/tor/utils.py +++ b/plinth/modules/tor/utils.py @@ -1,19 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Tor utility functions -""" +"""Tor utility functions.""" import glob import itertools -import json import augeas -from plinth import actions from plinth import app as app_module from plinth.daemon import app_is_running from plinth.modules.names.components import DomainName +from . import privileged + APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri', '/files/etc/apt/sources.list.d/*/*/uri') APT_TOR_PREFIX = 'tor+' @@ -21,8 +19,7 @@ APT_TOR_PREFIX = 'tor+' def get_status(initialized=True): """Return current Tor status.""" - output = actions.superuser_run('tor', ['get-status']) - status = json.loads(output) + status = privileged.get_status() hs_info = status['hidden_service'] hs_services = [] diff --git a/plinth/modules/tor/views.py b/plinth/modules/tor/views.py index 135a6f01b..9d7c3d4ab 100644 --- a/plinth/modules/tor/views.py +++ b/plinth/modules/tor/views.py @@ -1,19 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring Tor. -""" +"""FreedomBox app for configuring Tor.""" import logging from django.utils.translation import gettext_noop from django.views.generic.edit import FormView -from plinth import actions from plinth import app as app_module from plinth import operation as operation_module from plinth.modules import tor from plinth.views import AppView +from . import privileged from . import utils as tor_utils from .forms import TorForm @@ -81,49 +79,43 @@ def _apply_changes(old_status, new_status): def __apply_changes(old_status, new_status): """Apply the changes.""" - needs_restart = True - arguments = [] + needs_restart = False + arguments = {} app = app_module.App.get('tor') is_enabled = app.is_enabled() if old_status['relay_enabled'] != new_status['relay_enabled']: - arg_value = 'enable' if new_status['relay_enabled'] else 'disable' - arguments.extend(['--relay', arg_value]) + arguments['relay'] = new_status['relay_enabled'] + needs_restart = True if old_status['bridge_relay_enabled'] != \ new_status['bridge_relay_enabled']: - arg_value = 'enable' - if not new_status['bridge_relay_enabled']: - arg_value = 'disable' - arguments.extend(['--bridge-relay', arg_value]) + arguments['bridge_relay'] = new_status['bridge_relay_enabled'] + needs_restart = True if old_status['hs_enabled'] != new_status['hs_enabled']: - arg_value = 'enable' if new_status['hs_enabled'] else 'disable' - arguments.extend(['--hidden-service', arg_value]) + arguments['hidden_service'] = new_status['hs_enabled'] + needs_restart = True if old_status['apt_transport_tor_enabled'] != \ new_status['apt_transport_tor_enabled']: - arg_value = 'disable' - if is_enabled and new_status['apt_transport_tor_enabled']: - arg_value = 'enable' - arguments.extend(['--apt-transport-tor', arg_value]) - needs_restart = False + arguments['apt_transport_tor'] = ( + is_enabled and new_status['apt_transport_tor_enabled']) if old_status['use_upstream_bridges'] != \ new_status['use_upstream_bridges']: - arg_value = 'enable' if new_status[ - 'use_upstream_bridges'] else 'disable' - arguments.extend(['--use-upstream-bridges', arg_value]) + arguments['use_upstream_bridges'] = new_status['use_upstream_bridges'] + needs_restart = True if old_status['upstream_bridges'] != new_status['upstream_bridges']: - arguments.extend( - ['--upstream-bridges', new_status['upstream_bridges']]) + arguments['upstream_bridges'] = new_status['upstream_bridges'] + needs_restart = True if arguments: - actions.superuser_run('tor', ['configure'] + arguments) + privileged.configure(**arguments) if needs_restart and is_enabled: - actions.superuser_run('tor', ['restart']) + privileged.restart() status = tor_utils.get_status() tor.update_hidden_service_domain(status) diff --git a/plinth/modules/transmission/privileged.py b/plinth/modules/transmission/privileged.py index 3daceed37..b9fe96483 100644 --- a/plinth/modules/transmission/privileged.py +++ b/plinth/modules/transmission/privileged.py @@ -20,7 +20,7 @@ def get_configuration() -> dict[str, str]: @privileged -def merge_configuration(configuration: dict[str, Union[str, bool]]) -> None: +def merge_configuration(configuration: dict[str, Union[str, bool]]): """Merge given JSON configuration with existing configuration.""" current_configuration = _transmission_config.read_bytes() current_configuration = json.loads(current_configuration) diff --git a/plinth/modules/ttrss/__init__.py b/plinth/modules/ttrss/__init__.py index fc2fb9efa..d8ad1b026 100644 --- a/plinth/modules/ttrss/__init__.py +++ b/plinth/modules/ttrss/__init__.py @@ -1,12 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Tiny Tiny RSS. -""" +"""FreedomBox app to configure Tiny Tiny RSS.""" from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -17,7 +14,7 @@ from plinth.modules.users.components import UsersAndGroups from plinth.package import Packages, install from plinth.utils import Version, format_lazy -from . import manifest +from . import manifest, privileged _description = [ _('Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, ' @@ -97,20 +94,20 @@ class TTRSSApp(app_module.App): def enable(self): """Enable components and API access.""" super().enable() - actions.superuser_run('ttrss', ['enable-api-access']) + privileged.enable_api_access() # Try to set the domain to one of the available TLS domains - domain = get_domain() + domain = privileged.get_domain() if not domain or domain == 'localhost': from plinth.modules import names domain = next(names.get_available_tls_domains(), None) - set_domain(domain) + privileged.set_domain(domain) def setup(self, old_version): """Install and configure the app.""" - actions.superuser_run('ttrss', ['pre-setup']) + privileged.pre_setup() super().setup(old_version) - actions.superuser_run('ttrss', ['setup']) + privileged.setup() self.enable() def force_upgrade(self, packages): @@ -124,30 +121,19 @@ class TTRSSApp(app_module.App): return False install(['tt-rss'], force_configuration='new') - actions.superuser_run('ttrss', ['setup']) + privileged.setup() return True class TTRSSBackupRestore(BackupRestore): - """Component to backup/restore TT-RSS""" + """Component to backup/restore TT-RSS.""" def backup_pre(self, packet): """Save database contents.""" super().backup_pre(packet) - actions.superuser_run('ttrss', ['dump-database']) + privileged.dump_database() def restore_post(self, packet): """Restore database contents.""" super().restore_post(packet) - actions.superuser_run('ttrss', ['restore-database']) - - -def get_domain(): - """Read TLS domain from tt-rss config file.""" - return actions.superuser_run('ttrss', ['get-domain']).strip() - - -def set_domain(domain): - """Set the TLS domain in tt-rss configuration file.""" - if domain: - actions.superuser_run('ttrss', ['set-domain', domain]) + privileged.restore_database() diff --git a/actions/ttrss b/plinth/modules/ttrss/privileged.py old mode 100755 new mode 100644 similarity index 69% rename from actions/ttrss rename to plinth/modules/ttrss/privileged.py index 3ae8caffb..dcc242ef4 --- a/actions/ttrss +++ b/plinth/modules/ttrss/privileged.py @@ -1,16 +1,14 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Tiny Tiny RSS. -""" +"""Configure Tiny Tiny RSS.""" -import argparse import os import subprocess +from typing import Optional import augeas from plinth import action_utils +from plinth.actions import privileged CONFIG_FILE = '/etc/tt-rss/config.php' DEFAULT_FILE = '/etc/default/tt-rss' @@ -18,36 +16,15 @@ DATABASE_FILE = '/etc/tt-rss/database.php' DB_BACKUP_FILE = '/var/lib/plinth/backups-data/ttrss-database.sql' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('pre-setup', help='Perform pre-setup operations') - subparsers.add_parser('setup', help='Setup Tiny Tiny RSS configuration') - subparsers.add_parser('enable-api-access', help='Enable Tiny Tiny RSS API') - subparsers.add_parser('dump-database', help='Dump database to file') - subparsers.add_parser('restore-database', - help='Restore database from file') - subparsers.add_parser('get-domain', - help='Get the domain set for Tiny Tiny RSS.') - set_domain = subparsers.add_parser( - 'set-domain', help='Set the domain to be used by Tiny Tiny RSS.') - set_domain.add_argument( - 'domain_name', - help='The domain name that will be used by Tiny Tiny RSS.') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_pre_setup(_): +@privileged +def pre_setup(): """Preseed debconf values before packages are installed.""" action_utils.debconf_set_selections( ['tt-rss tt-rss/database-type string pgsql']) -def subcommand_get_domain(_): +@privileged +def get_domain() -> Optional[str]: """Get the domain set for Tiny Tiny RSS.""" aug = load_augeas() @@ -55,12 +32,18 @@ def subcommand_get_domain(_): for match in aug.match('/files' + CONFIG_FILE + '/define'): if aug.get(match) == 'SELF_URL_PATH': url = aug.get(match + '/value').strip("'") - print(urlparse(url).netloc) + return urlparse(url).netloc + + return None -def subcommand_set_domain(args): +@privileged +def set_domain(domain_name: Optional[str]): """Set the domain to be used by Tiny Tiny RSS.""" - url = f"'https://{args.domain_name}/tt-rss/'" + if not domain_name: + return + + url = f"'https://{domain_name}/tt-rss/'" aug = load_augeas() for match in aug.match('/files' + CONFIG_FILE + '/define'): @@ -70,7 +53,8 @@ def subcommand_set_domain(args): aug.save() -def subcommand_setup(_): +@privileged +def setup(): """Setup Tiny Tiny RSS configuration.""" aug = load_augeas() @@ -96,7 +80,8 @@ def subcommand_setup(_): action_utils.service_restart('tt-rss') -def subcommand_enable_api_access(_): +@privileged +def enable_api_access(): """Enable API access so that tt-rss can be accessed through mobile app.""" import psycopg2 # Only available post installation @@ -123,14 +108,16 @@ def subcommand_enable_api_access(_): connection.close() -def subcommand_dump_database(_): +@privileged +def dump_database(): """Dump database to file.""" os.makedirs(os.path.dirname(DB_BACKUP_FILE), exist_ok=True) with open(DB_BACKUP_FILE, 'w', encoding='utf-8') as db_backup_file: _run_as_postgres(['pg_dump', 'ttrss'], stdout=db_backup_file) -def subcommand_restore_database(_): +@privileged +def restore_database(): """Restore database from file.""" _run_as_postgres(['dropdb', 'ttrss']) _run_as_postgres(['createdb', 'ttrss']) @@ -155,16 +142,3 @@ def load_augeas(): aug.set('/augeas/load/Phpvars/incl[last() + 1]', DATABASE_FILE) aug.load() return aug - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/ttrss/tests/test_functional.py b/plinth/modules/ttrss/tests/test_functional.py index b47202b6e..8ca0d62ef 100644 --- a/plinth/modules/ttrss/tests/test_functional.py +++ b/plinth/modules/ttrss/tests/test_functional.py @@ -12,38 +12,25 @@ APP_ID = 'ttrss' pytestmark = [pytest.mark.apps, pytest.mark.ttrss, pytest.mark.sso] -@pytest.fixture(scope='module', autouse=True) -def fixture_background(session_browser): - """Login and install the app.""" - functional.login(session_browser) - functional.install(session_browser, APP_ID) - yield - functional.app_disable(session_browser, APP_ID) +class TestTTRSSApp(functional.BaseAppTests): + """Class to customize basic app tests for TTRSS.""" + app_name = 'ttrss' + has_service = True + has_web = True -def test_enable_disable(session_browser): - """Test enabling the app.""" - functional.app_disable(session_browser, APP_ID) + @pytest.mark.backups + def test_backup_restore(self, session_browser): + """Test backup and restore of app data.""" + functional.app_enable(session_browser, APP_ID) + _subscribe(session_browser) + functional.backup_create(session_browser, APP_ID, 'test_ttrss') - functional.app_enable(session_browser, APP_ID) - assert functional.service_is_running(session_browser, APP_ID) + _unsubscribe(session_browser) + functional.backup_restore(session_browser, APP_ID, 'test_ttrss') - functional.app_disable(session_browser, APP_ID) - assert functional.service_is_not_running(session_browser, APP_ID) - - -@pytest.mark.backups -def test_backup_restore(session_browser): - """Test backup and restore of app data.""" - functional.app_enable(session_browser, APP_ID) - _subscribe(session_browser) - functional.backup_create(session_browser, APP_ID, 'test_ttrss') - - _unsubscribe(session_browser) - functional.backup_restore(session_browser, APP_ID, 'test_ttrss') - - assert functional.service_is_running(session_browser, APP_ID) - assert _is_subscribed(session_browser) + assert functional.service_is_running(session_browser, APP_ID) + assert _is_subscribed(session_browser) def _ttrss_load_main_interface(browser): diff --git a/plinth/modules/ttrss/views.py b/plinth/modules/ttrss/views.py index c71be5ae0..244aa462e 100644 --- a/plinth/modules/ttrss/views.py +++ b/plinth/modules/ttrss/views.py @@ -1,28 +1,33 @@ # SPDX-License-Identifier: AGPL-3.0-or-later +"""Django views for Tiny Tiny RSS app.""" from django.contrib import messages from django.utils.translation import gettext_lazy as _ from plinth.forms import TLSDomainForm -from plinth.modules import ttrss from plinth.views import AppView +from . import privileged + class TTRSSAppView(AppView): + """Show TTRSS app main view.""" + app_id = 'ttrss' form_class = TLSDomainForm def get_initial(self): """Return the values to fill in the form.""" initial = super().get_initial() - initial['domain'] = ttrss.get_domain() + initial['domain'] = privileged.get_domain() return initial def form_valid(self, form): """Change the domain of TT-RSS app.""" data = form.cleaned_data - if ttrss.get_domain() != data['domain']: - ttrss.set_domain(data['domain']) + old_data = form.initial + if old_data['domain'] != data['domain']: + privileged.set_domain(data['domain']) messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/upgrades/__init__.py b/plinth/modules/upgrades/__init__.py index a530f868e..4a732df83 100644 --- a/plinth/modules/upgrades/__init__.py +++ b/plinth/modules/upgrades/__init__.py @@ -1,9 +1,6 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for upgrades. -""" +"""FreedomBox app for upgrades.""" -import json import logging import os import subprocess @@ -13,14 +10,13 @@ from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_noop import plinth -from plinth import actions from plinth import app as app_module from plinth import cfg, glib, kvstore, menu from plinth.daemon import RelatedDaemon from plinth.modules.backups.components import BackupRestore from plinth.package import Packages -from . import manifest +from . import manifest, privileged first_boot_steps = [ { @@ -48,10 +44,6 @@ BACKPORTS_REQUESTED_KEY = 'upgrades_backports_requested' DIST_UPGRADE_ENABLED_KEY = 'upgrades_dist_upgrade_enabled' -SOURCES_LIST = '/etc/apt/sources.list' - -BACKPORTS_SOURCES_LIST = '/etc/apt/sources.list.d/freedombox2.list' - logger = logging.getLogger(__name__) @@ -140,11 +132,11 @@ class UpgradesApp(app_module.App): # Enable automatic upgrades but only on first install if not old_version and not cfg.develop: - actions.superuser_run('upgrades', ['enable-auto']) + privileged.enable_auto() # Update apt preferences whenever on first install and on version # increment. - actions.superuser_run('upgrades', ['setup']) + privileged.setup() # When upgrading from a version without first boot wizard for # backports, assume backports have been requested. @@ -161,30 +153,10 @@ class UpgradesApp(app_module.App): setup_repositories(None) -def is_enabled(): - """Return whether the module is enabled.""" - output = actions.run('upgrades', ['check-auto']) - return 'True' in output.split() - - -def enable(): - """Enable the module.""" - actions.superuser_run('upgrades', ['enable-auto']) - - -def disable(): - """Disable the module.""" - actions.superuser_run('upgrades', ['disable-auto']) - - def setup_repositories(_): """Setup apt repositories for backports.""" if is_backports_requested(): - command = ['activate-backports'] - if cfg.develop: - command.append('--develop') - - actions.superuser_run('upgrades', command) + privileged.activate_backports(cfg.develop) def check_dist_upgrade(_): @@ -196,12 +168,8 @@ def check_dist_upgrade(_): def try_start_dist_upgrade(test=False): """Try to start dist upgrade.""" from plinth.notification import Notification - command = ['start-dist-upgrade'] - if test: - command.append('--test') - output = actions.superuser_run('upgrades', command) - result = json.loads(output) + result = privileged.start_dist_upgrade(test) dist_upgrade_started = result['dist_upgrade_started'] reason = result['reason'] if 'found-previous' in reason: @@ -270,7 +238,7 @@ def set_dist_upgrade_enabled(enabled=True): def is_backports_enabled(): """Return whether backports are enabled in the system configuration.""" - return os.path.exists(BACKPORTS_SOURCES_LIST) + return os.path.exists(privileged.BACKPORTS_SOURCES_LIST) def get_current_release(): diff --git a/actions/upgrades b/plinth/modules/upgrades/privileged.py old mode 100755 new mode 100644 similarity index 75% rename from actions/upgrades rename to plinth/modules/upgrades/privileged.py index 3f12ea4f7..43a2c2ea3 --- a/actions/upgrades +++ b/plinth/modules/upgrades/privileged.py @@ -1,30 +1,26 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configures or runs unattended-upgrades -""" +"""Configure or run unattended-upgrades.""" -import argparse -import json import logging import os import pathlib import re import subprocess -import sys import time -from typing import List, Tuple +from typing import List, Tuple, Union from plinth.action_utils import (apt_hold, apt_hold_flag, apt_hold_freedombox, apt_unhold_freedombox, debconf_set_selections, is_package_manager_busy, run_apt_command, service_daemon_reload, service_restart) +from plinth.actions import privileged from plinth.modules.apache.components import check_url from plinth.modules.snapshot import is_apt_snapshots_enabled from plinth.modules.snapshot import is_supported as snapshot_is_supported from plinth.modules.snapshot import load_augeas as snapshot_load_augeas -from plinth.modules.upgrades import (BACKPORTS_SOURCES_LIST, SOURCES_LIST, - get_current_release, is_backports_current) + +SOURCES_LIST = '/etc/apt/sources.list' +BACKPORTS_SOURCES_LIST = '/etc/apt/sources.list.d/freedombox2.list' AUTO_CONF_FILE = '/etc/apt/apt.conf.d/20auto-upgrades' LOG_FILE = '/var/log/unattended-upgrades/unattended-upgrades.log' @@ -32,7 +28,8 @@ DPKG_LOG_FILE = '/var/log/unattended-upgrades/unattended-upgrades-dpkg.log' RELEASE_FILE_URL = \ 'https://deb.debian.org/debian/dists/{}/Release' -APT_PREFERENCES_FREEDOMBOX = '''Explanation: This file is managed by FreedomBox, do not edit. +APT_PREFERENCES_FREEDOMBOX = \ + '''Explanation: This file is managed by FreedomBox, do not edit. Explanation: Allow carefully selected updates to 'freedombox' from backports. Package: src:freedombox Pin: release a={}-backports @@ -42,7 +39,8 @@ Pin-Priority: 500 # Whenever these preferences needs to change, increment the version number # upgrades app. This ensures that setup is run again and the new contents are # overwritten on the old file. -APT_PREFERENCES_APPS = '''Explanation: This file is managed by FreedomBox, do not edit. +APT_PREFERENCES_APPS = \ + '''Explanation: This file is managed by FreedomBox, do not edit. Explanation: matrix-synapse shall not be available in Debian stable but Explanation: only in backports. Upgrade priority of packages that have needed Explanation: versions only in backports. @@ -104,7 +102,7 @@ Description=Upgrade to new stable Debian release [Service] Type=oneshot -ExecStart=/usr/share/plinth/actions/upgrades dist-upgrade +ExecStart=/usr/share/plinth/actions/actions upgrades dist_upgrade --no-args KillMode=process TimeoutSec=12hr ''' @@ -116,46 +114,18 @@ dist_upgrade_flag = pathlib.Path( '/var/lib/freedombox/dist-upgrade-in-progress') -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('run', help='Upgrade packages on the system') - subparsers.add_parser('check-auto', - help='Check if automatic upgrades are enabled') - subparsers.add_parser('enable-auto', help='Enable automatic upgrades') - subparsers.add_parser('disable-auto', help='Disable automatic upgrades.') - subparsers.add_parser('get-log', help='Print the automatic upgrades log') - - subparsers.add_parser('setup', help='Setup apt preferences') - - activate_backports = subparsers.add_parser( - 'activate-backports', help='Activate backports if possible') - activate_backports.add_argument('--develop', required=False, default=False, - action='store_true', - help='Development mode') - - start_dist_upgrade = subparsers.add_parser( - 'start-dist-upgrade', help='Check and start dist upgrade process') - start_dist_upgrade.add_argument( - '--test', required=False, default=False, action='store_true', - help='Test dist-upgrade from stable to testing') - subparsers.add_parser('dist-upgrade', help='Perform dist upgrade') - - subparsers.required = True - return parser.parse_args() - - def _release_held_freedombox(): - """In case freedombox package was left in held state by an interrupted - process, release it.""" + """If freedombox package was left in held state, release it. + + This can happen due to an interrupted process. + """ if apt_hold_flag.exists() and not is_package_manager_busy(): apt_unhold_freedombox() -def _run(): - """Run unattended-upgrades""" +@privileged +def run(): + """Run unattended-upgrades.""" subprocess.run(['dpkg', '--configure', '-a'], check=False) run_apt_command(['--fix-broken', 'install']) _release_held_freedombox() @@ -166,18 +136,6 @@ def _run(): start_new_session=True) -def subcommand_run(_): - """Run unattended-upgrades""" - try: - _run() - except FileNotFoundError: - print('Error: systemctl is not available.', file=sys.stderr) - sys.exit(2) - except Exception as error: - print('Error: {0}'.format(error), file=sys.stderr) - sys.exit(3) - - def _check_auto() -> bool: """Check if automatic upgrades are enabled.""" arguments = [ @@ -193,45 +151,48 @@ def _check_auto() -> bool: return bool(update_interval) -def subcommand_check_auto(_): - """Check if automatic upgrades are enabled""" - try: - print(_check_auto()) - except subprocess.CalledProcessError as error: - print('Error: {0}'.format(error), file=sys.stderr) - sys.exit(1) +@privileged +def check_auto() -> bool: + """Check if automatic upgrades are enabled.""" + return _check_auto() -def subcommand_enable_auto(_): - """Enable automatic upgrades""" +@privileged +def enable_auto(): + """Enable automatic upgrades.""" with open(AUTO_CONF_FILE, 'w', encoding='utf-8') as conffile: conffile.write('APT::Periodic::Update-Package-Lists "1";\n') conffile.write('APT::Periodic::Unattended-Upgrade "1";\n') -def subcommand_disable_auto(_): - """Disable automatic upgrades""" +@privileged +def disable_auto(): + """Disable automatic upgrades.""" with open(AUTO_CONF_FILE, 'w', encoding='utf-8') as conffile: conffile.write('APT::Periodic::Update-Package-Lists "0";\n') conffile.write('APT::Periodic::Unattended-Upgrade "0";\n') -def subcommand_get_log(_): - """Print the automatic upgrades log.""" +@privileged +def get_log() -> str: + """Return the automatic upgrades log.""" + log_lines = [] try: - print('==> ' + os.path.basename(LOG_FILE)) + log_lines.append('==> ' + os.path.basename(LOG_FILE)) with open(LOG_FILE, 'r', encoding='utf-8') as file_handle: - print(file_handle.read()) + log_lines.append(file_handle.read()) except IOError: pass try: - print('==> ' + os.path.basename(DPKG_LOG_FILE)) + log_lines.append('==> ' + os.path.basename(DPKG_LOG_FILE)) with open(DPKG_LOG_FILE, 'r', encoding='utf-8') as file_handle: - print(file_handle.read()) + log_lines.append(file_handle.read()) except IOError: pass + return '\n'.join(log_lines) + def _get_protocol() -> str: """Return the protocol to use for newly added repository sources.""" @@ -278,8 +239,10 @@ def _check_and_backports_sources(develop=False): if os.path.exists(old_sources_list): os.remove(old_sources_list) + from plinth.modules.upgrades import (get_current_release, + is_backports_current) if is_backports_current(): - print('Repositories list up-to-date. Skipping update.') + logging.info('Repositories list up-to-date. Skipping update.') return try: @@ -290,25 +253,26 @@ def _check_and_backports_sources(develop=False): for line in default_origin.readlines() ] except FileNotFoundError: - print('Could not open /etc/dpkg/origins/default') + logging.info('Could not open /etc/dpkg/origins/default') return if not any(matches): - print('System is running a derivative of Debian. Skip enabling ' - 'backports.') + logging.info('System is running a derivative of Debian. Skip enabling ' + 'backports.') return release, dist = get_current_release() if release == 'unstable' or (release == 'testing' and not develop): - print(f'System release is {release}. Skip enabling backports.') + logging.info(f'System release is {release}. Skip enabling backports.') return protocol = _get_protocol() if protocol == 'tor+http': - print('Package download over Tor is enabled.') + logging.info('Package download over Tor is enabled.') if not _is_release_file_available(protocol, dist, backports=True): - print(f'Release file for {dist}-backports is not available yet.') + logging.info( + f'Release file for {dist}-backports is not available yet.') return print(f'{dist}-backports is now available. Adding to sources.') @@ -328,12 +292,14 @@ def _add_apt_preferences(): # Don't try to remove 50freedombox3.pref as this file is shipped with the # Debian package and is removed using maintainer scripts. + from plinth.modules.upgrades import get_current_release _, dist = get_current_release() if dist == 'sid': - print(f'System distribution is {dist}. Skip setting apt preferences ' - 'for backports.') + logging.info( + f'System distribution is {dist}. Skip setting apt preferences ' + 'for backports.') else: - print(f'Setting apt preferences for {dist}-backports.') + logging.info(f'Setting apt preferences for {dist}-backports.') with open(base_path / '50freedombox4.pref', 'w', encoding='utf-8') as file_handle: file_handle.write(APT_PREFERENCES_FREEDOMBOX.format(dist)) @@ -350,17 +316,20 @@ def _is_sufficient_free_space() -> bool: def _check_dist_upgrade(test_upgrade=False) -> Tuple[bool, str]: - """Check for new stable release, if updates are enabled, and if there is + """Check if a distribution upgrade be performed. + + Check for new stable release, if updates are enabled, and if there is enough free space for the dist upgrade. If test_upgrade is True, also check for upgrade to testing. - Returns (boolean, string) indicating if the upgrade is ready, and a reason + Return (boolean, string) indicating if the upgrade is ready, and a reason if not. """ if dist_upgrade_flag.exists(): return (True, 'found-previous') + from plinth.modules.upgrades import get_current_release release, dist = get_current_release() if release in ['unstable', 'testing']: return (False, f'already-{release}') @@ -429,18 +398,22 @@ def _check_dist_upgrade(test_upgrade=False) -> Tuple[bool, str]: def _take_snapshot_and_disable() -> bool: """Take a snapshot if supported and enabled, then disable snapshots. - Return whether snapshots shall be re-enabled at the end.""" + Return whether snapshots shall be re-enabled at the end. + """ if snapshot_is_supported(): print('Taking a snapshot before dist upgrade...', flush=True) - subprocess.run(['/usr/share/plinth/actions/snapshot', 'create'], - check=True) + subprocess.run([ + '/usr/share/plinth/actions/actions', 'snapshot', 'create', + '--no-args' + ], check=True) aug = snapshot_load_augeas() if is_apt_snapshots_enabled(aug): print('Disable apt snapshots during dist upgrade...', flush=True) subprocess.run([ - '/usr/share/plinth/actions/snapshot', 'disable-apt-snapshot', - 'yes' - ], check=True) + '/usr/share/plinth/actions/actions', + 'snapshot', + 'disable_apt_snapshot', + ], input='{"args": ["yes"], "kwargs": {}}'.encode(), check=True) return True else: print('Apt snapshots already disabled.', flush=True) @@ -456,39 +429,42 @@ def _restore_snapshots_config(reenable=False): if reenable: print('Re-enable apt snapshots...', flush=True) subprocess.run([ - '/usr/share/plinth/actions/snapshot', 'disable-apt-snapshot', 'no' - ], check=True) + '/usr/share/plinth/actions/actions', 'snapshot', + 'disable_apt_snapshot' + ], input='{"args": ["no"], "kwargs": {}}'.encode(), check=True) def _disable_searx() -> bool: """If searx is enabled, disable it until we can upgrade it properly. - Return whether searx was originally enabled.""" + Return whether searx was originally enabled. + """ searx_is_enabled = pathlib.Path( '/etc/uwsgi/apps-enabled/searx.ini').exists() if searx_is_enabled: print('Disabling searx...', flush=True) - subprocess.run([ - '/usr/share/plinth/actions/apache', 'uwsgi-disable', '--name', - 'searx' - ], check=True) + subprocess.run( + ['/usr/share/plinth/actions/actions', 'apache', 'uwsgi_disable'], + input='{"args": ["searx"], "kwargs": {}}'.encode(), check=True) return searx_is_enabled def _update_searx(reenable=False): """If searx is installed, update search engines list. - Re-enable if previously enabled.""" + + Re-enable if previously enabled. + """ if pathlib.Path('/etc/searx/settings.yml').exists(): print('Updating searx search engines list...', flush=True) - subprocess.run(['/usr/share/plinth/actions/searx', 'setup'], - check=True) + subprocess.run([ + '/usr/share/plinth/actions/actions', 'searx', 'setup', '--no-args' + ], check=True) if reenable: print('Re-enabling searx after upgrade...', flush=True) subprocess.run([ - '/usr/share/plinth/actions/apache', 'uwsgi-enable', '--name', - 'searx' - ], check=True) + '/usr/share/plinth/actions/actions', 'apache', 'uwsgi_enable' + ], input='{"args": ["searx"], "kwargs": {}}'.encode(), check=True) def _perform_dist_upgrade(): @@ -564,19 +540,20 @@ def _perform_dist_upgrade(): dist_upgrade_flag.unlink() -def subcommand_setup(_): +@privileged +def setup(): """Setup apt preferences.""" _add_apt_preferences() -def subcommand_activate_backports(arguments): +@privileged +def activate_backports(develop: bool = False): """Setup software repositories needed for FreedomBox. Repositories list for now only contains the backports. If the file exists, assume that it contains backports. - """ - _check_and_backports_sources(arguments.develop) + _check_and_backports_sources(develop) def _start_dist_upgrade_service(): @@ -592,7 +569,8 @@ def _start_dist_upgrade_service(): start_new_session=True) -def subcommand_start_dist_upgrade(arguments): +@privileged +def start_dist_upgrade(test: bool = False) -> dict[str, Union[str, bool]]: """Start dist upgrade process. Check if a new stable release is available, and start dist-upgrade process @@ -600,31 +578,14 @@ def subcommand_start_dist_upgrade(arguments): """ _release_held_freedombox() - upgrade_ready, reason = _check_dist_upgrade(arguments.test) + upgrade_ready, reason = _check_dist_upgrade(test) if upgrade_ready: _start_dist_upgrade_service() - print( - json.dumps({ - 'dist_upgrade_started': upgrade_ready, - 'reason': reason, - })) + return {'dist_upgrade_started': upgrade_ready, 'reason': reason} -def subcommand_dist_upgrade(_): - """Perform major distribution upgrade. - """ +@privileged +def dist_upgrade(): + """Perform major distribution upgrade.""" _perform_dist_upgrade() - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/upgrades/views.py b/plinth/modules/upgrades/views.py index 7d5e6cd23..0736ff000 100644 --- a/plinth/modules/upgrades/views.py +++ b/plinth/modules/upgrades/views.py @@ -1,7 +1,6 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for upgrades. -""" +"""FreedomBox app for upgrades.""" + import subprocess from apt.cache import Cache @@ -13,34 +12,38 @@ from django.utils.translation import gettext as _ from django.views.generic import TemplateView from django.views.generic.edit import FormView -from plinth import __version__, actions, package -from plinth.errors import ActionError +from plinth import __version__ from plinth.modules import first_boot, upgrades +from plinth.privileged import packages as packages_privileged from plinth.views import AppView +from . import privileged from .forms import BackportsFirstbootForm, ConfigureForm, UpdateFirstbootForm class UpgradesConfigurationView(AppView): """Serve configuration page.""" + form_class = ConfigureForm success_url = reverse_lazy('upgrades:index') template_name = "upgrades_configure.html" app_id = 'upgrades' def get_initial(self): + """Return the initial values for the form.""" return { - 'auto_upgrades_enabled': upgrades.is_enabled(), + 'auto_upgrades_enabled': privileged.check_auto(), 'dist_upgrade_enabled': upgrades.is_dist_upgrade_enabled() } def get_context_data(self, *args, **kwargs): + """Add additional context data for template.""" context = super().get_context_data(*args, **kwargs) context['can_activate_backports'] = upgrades.can_activate_backports() context['is_backports_requested'] = upgrades.is_backports_requested() context['is_busy'] = (_is_updating() - or package.is_package_manager_busy()) - context['log'] = get_log() + or packages_privileged.is_package_manager_busy()) + context['log'] = privileged.get_log() context['refresh_page_sec'] = 3 if context['is_busy'] else None context['version'] = __version__ context['new_version'] = is_newer_version_available() @@ -58,10 +61,10 @@ class UpgradesConfigurationView(AppView): try: if new_status['auto_upgrades_enabled']: - upgrades.enable() + privileged.enable_auto() else: - upgrades.disable() - except ActionError as exception: + privileged.disable_auto() + except Exception as exception: error = exception.args[2] messages.error( self.request, @@ -89,14 +92,14 @@ class UpgradesConfigurationView(AppView): def is_newer_version_available(): - """Returns whether a newer Freedombox version is available.""" + """Return whether a newer Freedombox version is available.""" cache = Cache() freedombox = cache['freedombox'] return not freedombox.candidate.is_installed def get_os_release(): - """Returns the Debian release number and name.""" + """Return the Debian release number and name.""" output = 'Error: Cannot read PRETTY_NAME in /etc/os-release.' with open('/etc/os-release', 'r', encoding='utf-8') as release_file: for line in release_file: @@ -107,11 +110,6 @@ def get_os_release(): return output -def get_log(): - """Return the current log for unattended upgrades.""" - return actions.superuser_run('upgrades', ['get-log']) - - def _is_updating(): """Check if manually triggered update is running.""" command = ['systemctl', 'is-active', 'freedombox-manual-upgrade'] @@ -124,9 +122,9 @@ def upgrade(request): """Serve the upgrade page.""" if request.method == 'POST': try: - actions.superuser_run('upgrades', ['run']) + privileged.run() messages.success(request, _('Upgrade process started.')) - except ActionError: + except Exception: messages.error(request, _('Starting upgrade failed.')) return redirect(reverse_lazy('upgrades:index')) @@ -144,6 +142,7 @@ def activate_backports(request): class BackportsFirstbootView(FormView): """View to configure backports during first boot wizard.""" + template_name = 'backports-firstboot.html' form_class = BackportsFirstbootForm @@ -179,6 +178,7 @@ class BackportsFirstbootView(FormView): class UpdateFirstbootView(FormView): """View to run initial update during first boot wizard.""" + template_name = 'update-firstboot.html' form_class = UpdateFirstbootForm @@ -197,7 +197,7 @@ class UpdateFirstbootView(FormView): """Run update if selected, and mark step as done.""" self.update = form.cleaned_data['update_now'] if self.update: - actions.superuser_run('upgrades', ['run']) + privileged.run() first_boot.mark_step_done('initial_update') return super().form_valid(form) @@ -205,12 +205,13 @@ class UpdateFirstbootView(FormView): class UpdateFirstbootProgressView(TemplateView): """View to show initial update progress.""" + template_name = 'update-firstboot-progress.html' def get_context_data(self, *args, **kwargs): context = super().get_context_data(*args, **kwargs) context['is_busy'] = (_is_updating() - or package.is_package_manager_busy()) + or packages_privileged.is_package_manager_busy()) context['next_step'] = first_boot.next_step() context['refresh_page_sec'] = 3 if context['is_busy'] else None return context diff --git a/plinth/modules/users/__init__.py b/plinth/modules/users/__init__.py index 4f4d18784..5e7f68e89 100644 --- a/plinth/modules/users/__init__.py +++ b/plinth/modules/users/__init__.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to manage users. -""" +"""FreedomBox app to manage users.""" import grp import subprocess @@ -9,12 +7,13 @@ import subprocess from django.utils.text import format_lazy from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, menu from plinth.daemon import Daemon from plinth.package import Packages +from plinth.privileged import service as service_privileged +from . import privileged from .components import UsersAndGroups first_boot_steps = [ @@ -91,10 +90,10 @@ class UsersApp(app_module.App): """Install and configure the app.""" super().setup(old_version) if not old_version: - actions.superuser_run('users', ['first-setup']) + privileged.first_setup() - actions.superuser_run('users', ['setup']) - create_group('freedombox-share') + privileged.setup() + privileged.create_group('freedombox-share') def _diagnose_ldap_entry(search_item): @@ -114,21 +113,9 @@ def _diagnose_ldap_entry(search_item): return [testname, result] -def create_group(group): - """Add an LDAP group.""" - actions.superuser_run('users', options=['create-group', group]) - - -def remove_group(group): - """Remove an LDAP group.""" - actions.superuser_run('users', options=['remove-group', group]) - - def get_last_admin_user(): """If there is only one admin user return its name else return None.""" - output = actions.superuser_run('users', ['get-group-users', 'admin']) - admin_users = output.strip().split('\n') - + admin_users = privileged.get_group_users('admin') if len(admin_users) == 1 and admin_users[0]: return admin_users[0] @@ -142,7 +129,6 @@ def add_user_to_share_group(username, service=None): except KeyError: group_members = [] if username not in group_members: - actions.superuser_run( - 'users', ['add-user-to-group', username, 'freedombox-share']) + privileged.add_user_to_group(username, 'freedombox-share') if service: - actions.superuser_run('service', ['try-restart', service]) + service_privileged.try_restart(service) diff --git a/plinth/modules/users/forms.py b/plinth/modules/users/forms.py index 5dd6b7a74..64d379c45 100644 --- a/plinth/modules/users/forms.py +++ b/plinth/modules/users/forms.py @@ -1,4 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later +"""Django forms for user management.""" import pwd import re @@ -15,13 +16,12 @@ from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy import plinth.forms -from plinth import actions -from plinth.errors import ActionError +import plinth.modules.ssh.privileged as ssh_privileged from plinth.modules import first_boot from plinth.modules.security import set_restricted_access from plinth.utils import is_user_admin -from . import get_last_admin_user +from . import get_last_admin_user, privileged from .components import UsersAndGroups @@ -73,11 +73,13 @@ USERNAME_FIELD = forms.CharField( class PasswordConfirmForm(forms.Form): """Password confirmation form.""" + confirm_password = forms.CharField( widget=forms.PasswordInput, label=gettext_lazy('Authorization Password')) def __init__(self, *args, **kwargs): + """Initialize form.""" super().__init__(*args, **kwargs) self.fields['confirm_password'].help_text = _( @@ -102,6 +104,7 @@ class CreateUserForm(ValidNewUsernameCheckMixin, Include options to add user to groups. """ + username = USERNAME_FIELD groups = forms.MultipleChoiceField( choices=UsersAndGroups.get_group_choices, @@ -119,6 +122,7 @@ class CreateUserForm(ValidNewUsernameCheckMixin, class Meta(UserCreationForm.Meta): """Metadata to control automatic form building.""" + fields = ('username', 'password1', 'password2', 'groups', 'language', 'confirm_password') @@ -142,14 +146,11 @@ class CreateUserForm(ValidNewUsernameCheckMixin, auth_username = self.request.user.username confirm_password = self.cleaned_data['confirm_password'] - process_input = '{0}\n{1}'.format(self.cleaned_data['password1'], - confirm_password).encode() try: - actions.superuser_run('users', [ - 'create-user', - user.get_username(), '--auth-user', auth_username - ], input=process_input) - except ActionError as error: + privileged.create_user(user.get_username(), + self.cleaned_data['password1'], + auth_username, confirm_password) + except Exception as error: messages.error( self.request, _('Creating LDAP user failed: {error}'.format( @@ -157,12 +158,10 @@ class CreateUserForm(ValidNewUsernameCheckMixin, for group in self.cleaned_data['groups']: try: - actions.superuser_run('users', [ - 'add-user-to-group', - user.get_username(), group, '--auth-user', - auth_username - ], input=confirm_password.encode()) - except ActionError as error: + privileged.add_user_to_group(user.get_username(), group, + auth_username, + confirm_password) + except Exception as error: messages.error( self.request, _('Failed to add new user to {group} group: {error}'). @@ -177,6 +176,7 @@ class CreateUserForm(ValidNewUsernameCheckMixin, class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm, plinth.forms.LanguageSelectionFormMixin, forms.ModelForm): """When user info is changed, also updates LDAP user.""" + username = USERNAME_FIELD ssh_keys = forms.CharField( label=gettext_lazy('Authorized SSH Keys'), required=False, @@ -191,6 +191,7 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm, class Meta: """Metadata to control automatic form building.""" + fields = ('username', 'groups', 'ssh_keys', 'language', 'is_active', 'confirm_password') model = User @@ -253,18 +254,13 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm, user.save() self.save_m2m() - output = actions.superuser_run('users', - ['get-user-groups', self.username]) - old_groups = output.strip().split('\n') + old_groups = privileged.get_user_groups(self.username) old_groups = [group for group in old_groups if group] if self.username != user.get_username(): try: - actions.superuser_run( - 'users', - ['rename-user', self.username, - user.get_username()]) - except ActionError: + privileged.rename_user(self.username, user.get_username()) + except Exception: messages.error(self.request, _('Renaming LDAP user failed.')) @@ -272,38 +268,28 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm, for old_group in old_groups: if old_group not in new_groups: try: - actions.superuser_run('users', [ - 'remove-user-from-group', - user.get_username(), old_group, '--auth-user', - auth_username - ], input=confirm_password.encode()) - except ActionError: + privileged.remove_user_from_group( + user.get_username(), old_group, auth_username, + confirm_password) + except Exception: messages.error(self.request, _('Failed to remove user from group.')) for new_group in new_groups: if new_group not in old_groups: try: - actions.superuser_run('users', [ - 'add-user-to-group', - user.get_username(), new_group, '--auth-user', - auth_username - ], input=confirm_password.encode()) - except ActionError: + privileged.add_user_to_group(user.get_username(), + new_group, auth_username, + confirm_password) + except Exception: messages.error(self.request, _('Failed to add user to group.')) try: - actions.superuser_run('ssh', [ - 'set-keys', - '--username', - user.get_username(), - '--keys', - self.cleaned_data['ssh_keys'].strip(), - '--auth-user', - auth_username, - ], input=confirm_password.encode()) - except ActionError: + ssh_privileged.set_keys(user.get_username(), + self.cleaned_data['ssh_keys'].strip(), + auth_username, confirm_password) + except Exception: messages.error(self.request, _('Unable to set SSH keys.')) is_active = self.cleaned_data['is_active'] @@ -313,14 +299,9 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, PasswordConfirmForm, else: status = 'inactive' try: - actions.superuser_run('users', [ - 'set-user-status', - user.get_username(), - status, - '--auth-user', - auth_username, - ], input=confirm_password.encode()) - except ActionError: + privileged.set_user_status(user.get_username(), status, + auth_username, confirm_password) + except Exception: messages.error(self.request, _('Failed to change user status.')) @@ -357,15 +338,11 @@ class UserChangePasswordForm(PasswordConfirmForm, SetPasswordForm): user = super().save(commit) auth_username = self.request.user.username if commit: - process_input = '{0}\n{1}'.format( - self.cleaned_data['new_password1'], - self.cleaned_data['confirm_password']).encode() try: - actions.superuser_run('users', [ - 'set-user-password', - user.get_username(), '--auth-user', auth_username - ], input=process_input) - except ActionError: + privileged.set_user_password( + user.get_username(), self.cleaned_data['new_password1'], + auth_username, self.cleaned_data['confirm_password']) + except Exception: messages.error(self.request, _('Changing LDAP user password failed.')) @@ -374,6 +351,7 @@ class UserChangePasswordForm(PasswordConfirmForm, SetPasswordForm): class FirstBootForm(ValidNewUsernameCheckMixin, auth.forms.UserCreationForm): """User module first boot step: create a new admin user.""" + username = USERNAME_FIELD def __init__(self, *args, **kwargs): @@ -388,23 +366,17 @@ class FirstBootForm(ValidNewUsernameCheckMixin, auth.forms.UserCreationForm): first_boot.mark_step_done('users_firstboot') try: - actions.superuser_run( - 'users', - ['create-user', - user.get_username(), '--auth-user', ''], - input=self.cleaned_data['password1'].encode()) - except ActionError as error: + privileged.create_user(user.get_username(), + self.cleaned_data['password1']) + except Exception as error: messages.error( self.request, _('Creating LDAP user failed: {error}'.format( error=error))) try: - actions.superuser_run( - 'users', - ['add-user-to-group', - user.get_username(), 'admin']) - except ActionError as error: + privileged.add_user_to_group(user.get_username(), 'admin') + except Exception as error: messages.error( self.request, _('Failed to add new user to admin group: {error}'.format( diff --git a/actions/users b/plinth/modules/users/privileged.py old mode 100755 new mode 100644 similarity index 52% rename from actions/users rename to plinth/modules/users/privileged.py index 759b847eb..099e24c44 --- a/actions/users +++ b/plinth/modules/users/privileged.py @@ -1,142 +1,53 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for the LDAP user directory -""" +"""Configuration helper for the LDAP user directory.""" -import argparse import logging import os import re import shutil import subprocess -import sys +from typing import Optional import augeas from plinth import action_utils, utils +from plinth.actions import privileged INPUT_LINES = None ACCESS_CONF = '/etc/security/access.conf' LDAPSCRIPTS_CONF = '/etc/ldapscripts/freedombox-ldapscripts.conf' -def parse_arguments(): - """Return parsed command line arguments as dictionary""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('first-setup', help='Perform initial setup of LDAP') - subparsers.add_parser('setup', help='Setup LDAP') - - subparser = subparsers.add_parser('create-user', - help='Create an LDAP user') - subparser.add_argument('username', help='Name of the LDAP user to create') - subparser.add_argument('--auth-user', required=True) - - subparser = subparsers.add_parser('remove-user', - help='Delete an LDAP user') - subparser.add_argument( - 'username', help='Name of the LDAP user to delete. If the username is ' - 'the last admin user, a password should be provided through STDIN.') - - subparser = subparsers.add_parser('rename-user', - help='Rename an LDAP user') - subparser.add_argument('oldusername', help='Old name of the LDAP user') - subparser.add_argument('newusername', help='New name of the LDAP user') - - subparser = subparsers.add_parser('set-user-password', - help='Set the password of an LDAP user') - subparser.add_argument( - 'username', help='Name of the LDAP user to set the password for') - subparser.add_argument('--auth-user', required=True) - - subparser = subparsers.add_parser('create-group', - help='Create an LDAP group') - subparser.add_argument('groupname', - help='Name of the LDAP group to create') - - subparser = subparsers.add_parser('rename-group', - help='Rename an LDAP group') - subparser.add_argument('old_groupname', - help='Name of the LDAP group to rename') - subparser.add_argument('new_groupname', help='Name of the new LDAP group') - - subparser = subparsers.add_parser('remove-group', - help='Delete an LDAP group') - subparser.add_argument('groupname', - help='Name of the LDAP group to delete') - - subparser = subparsers.add_parser( - 'get-user-groups', help='Get all the LDAP groups for an LDAP user') - subparser.add_argument('username', - help='LDAP user to retrieve the groups for') - - subparser = subparsers.add_parser('add-user-to-group', - help='Add an LDAP user to an LDAP group') - subparser.add_argument('username', help='LDAP user to add to group') - subparser.add_argument('groupname', help='LDAP group to add the user to') - subparser.add_argument('--auth-user', required=False) - - subparser = subparsers.add_parser('set-user-status', - help='Set user as active or inactive') - subparser.add_argument('username', help='User to change status') - subparser.add_argument('status', choices=['active', 'inactive'], - help='New status of the user') - subparser.add_argument('--auth-user', required=True) - - subparser = subparsers.add_parser( - 'remove-user-from-group', - help='Remove an LDAP user from an LDAP group') - subparser.add_argument('username', help='LDAP user to remove from group') - subparser.add_argument('groupname', - help='LDAP group to remove the user from') - subparser.add_argument('--auth-user', required=False) - - help_get_group_users = 'Get the list of all users in an LDAP group' - subparser = subparsers.add_parser('get-group-users', - help=help_get_group_users) - subparser.add_argument( - 'groupname', help='name of the LDAP group to get the ' - 'list of users') - - subparsers.required = True - return parser.parse_args() - - -def validate_user(username, must_be_admin=True): +def _validate_user(username, password, must_be_admin=True): """Validate a user.""" if must_be_admin: - admins = get_admin_users() + admins = _get_admin_users() if not admins: # any user is valid return if not username: - msg = 'Argument --auth-user is required' - raise argparse.ArgumentTypeError(msg) + raise PermissionError('Authentication user is required') if username not in admins: - msg = '"{}" is not authorized to perform this action'.format( - username) - raise argparse.ArgumentTypeError(msg) + msg = f'"{username}" is not authorized to perform this action' + raise PermissionError(msg) if not username: - msg = 'Argument --auth-user is required' - raise argparse.ArgumentTypeError(msg) + raise PermissionError('Authentication user is required') - validate_password(username) + _validate_password(username, password) -def validate_password(username): +def _validate_password(username, password): """Raise an error if the user password is invalid.""" - password = read_password(last=True) if not utils.is_authenticated_user(username, password): - raise argparse.ArgumentTypeError("Invalid credentials") + raise PermissionError('Invalid credentials') -def subcommand_first_setup(_): +@privileged +def first_setup(): """Perform initial setup of LDAP.""" # Avoid reconfiguration of slapd during module upgrades, because # this will move the existing database. @@ -147,19 +58,20 @@ def subcommand_first_setup(_): action_utils.dpkg_reconfigure('slapd', {'domain': 'thisbox'}) -def subcommand_setup(_): +@privileged +def setup(): """Setup LDAP.""" # Update pam configs for access and mkhomedir. subprocess.run(['pam-auth-update', '--package'], check=True) - configure_ldapscripts() + _configure_ldapscripts() - configure_ldap_authentication() + _configure_ldap_authentication() - configure_ldap_structure() + _configure_ldap_structure() -def configure_ldap_authentication(): +def _configure_ldap_authentication(): """Configure LDAP authentication.""" action_utils.dpkg_reconfigure( 'nslcd', { @@ -179,18 +91,18 @@ def configure_ldap_authentication(): action_utils.service_start('nslcd') -def configure_ldap_structure(): +def _configure_ldap_structure(): """Configure LDAP basic structure.""" was_running = action_utils.service_is_running('slapd') if not was_running: action_utils.service_start('slapd') - setup_admin() - create_organizational_unit('users') - create_organizational_unit('groups') + _setup_admin() + _create_organizational_unit('users') + _create_organizational_unit('groups') -def create_organizational_unit(unit): +def _create_organizational_unit(unit): """Create an organizational unit in LDAP.""" distinguished_name = 'ou={unit},dc=thisbox'.format(unit=unit) try: @@ -210,7 +122,7 @@ ou: {unit}'''.format(unit=unit) check=True) -def setup_admin(): +def _setup_admin(): """Remove LDAP admin password and Allow root to modify the users.""" process = subprocess.run([ 'ldapsearch', '-Q', '-L', '-L', '-L', '-Y', 'EXTERNAL', '-H', @@ -243,7 +155,7 @@ olcRootDN: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth ''') -def configure_ldapscripts(): +def _configure_ldapscripts(): """Set the configuration used by ldapscripts for later user management.""" # modify a copy of the config file shutil.copy('/etc/ldapscripts/ldapscripts.conf', LDAPSCRIPTS_CONF) @@ -266,7 +178,7 @@ def configure_ldapscripts(): aug.save() -def get_samba_users(): +def _get_samba_users(): """Get users from the Samba user database.""" # 'pdbedit -L' is better for listing users but is installed only with samba stdout = subprocess.check_output( @@ -274,14 +186,14 @@ def get_samba_users(): return re.findall(r'USER_(.*)\\0', stdout) -def delete_samba_user(username): +def _delete_samba_user(username): """Delete a Samba user.""" - if username in get_samba_users(): + if username in _get_samba_users(): subprocess.check_call(['smbpasswd', '-x', username]) - disconnect_samba_user(username) + _disconnect_samba_user(username) -def disconnect_samba_user(username): +def _disconnect_samba_user(username): """Disconnect a Samba user.""" try: subprocess.check_call(['pkill', '-U', username, 'smbd']) @@ -290,84 +202,63 @@ def disconnect_samba_user(username): raise -def get_input_lines(): - """Return list of input lines from stdin.""" - global INPUT_LINES - if INPUT_LINES is None: - INPUT_LINES = [line.strip() for line in sys.stdin] - return INPUT_LINES - - -def read_password(last=False): - """Return the password. - - Set last=True to read password from last line of the input. - - """ - line = -1 if last else 0 - return get_input_lines()[line] - - -def subcommand_create_user(arguments): +@privileged +def create_user(username: str, password: str, auth_user: Optional[str] = None, + auth_password: Optional[str] = None): """Create an LDAP user, set password and flush cache.""" - username = arguments.username - auth_user = arguments.auth_user - - validate_user(auth_user) + _validate_user(auth_user, auth_password) _run(['ldapadduser', username, 'users']) - password = read_password() - set_user_password(username, password) - flush_cache() - set_samba_user(username, password) + _set_user_password(username, password) + _flush_cache() + _set_samba_user(username, password) -def subcommand_remove_user(arguments): +@privileged +def remove_user(username: str, password: Optional[str] = None): """Remove an LDAP user.""" - username = arguments.username - groups = get_user_groups(username) + groups = _get_user_groups(username) # require authentication if the user is last admin user - if get_group_users('admin') == [username]: - validate_password(username) + if _get_group_users('admin') == [username]: + _validate_password(username, password) - delete_samba_user(username) + _delete_samba_user(username) for group in groups: - remove_user_from_group(username, group) + _remove_user_from_group(username, group) _run(['ldapdeleteuser', username]) - flush_cache() + _flush_cache() -def subcommand_rename_user(arguments): +@privileged +def rename_user(old_username: str, new_username: str): """Rename an LDAP user.""" - old_username = arguments.oldusername - new_username = arguments.newusername - groups = get_user_groups(old_username) + groups = _get_user_groups(old_username) - delete_samba_user(old_username) + _delete_samba_user(old_username) for group in groups: - remove_user_from_group(old_username, group) + _remove_user_from_group(old_username, group) _run(['ldaprenameuser', old_username, new_username]) for group in groups: - add_user_to_group(new_username, group) + _add_user_to_group(new_username, group) - flush_cache() + _flush_cache() -def set_user_password(username, password): +def _set_user_password(username, password): """Set a user's password.""" process = _run(['slappasswd', '-s', password], stdout=subprocess.PIPE) password = process.stdout.decode().strip() _run(['ldapsetpasswd', username, password]) -def set_samba_user(username, password): +def _set_samba_user(username, password): """Insert a user to the Samba database. If a user already exists, update password. @@ -379,24 +270,21 @@ def set_samba_user(username, password): raise RuntimeError('Unable to add Samba user: ', proc.stderr) -def subcommand_set_user_password(arguments): +@privileged +def set_user_password(username: str, password: str, auth_user: str, + auth_password: str): """Set a user's password.""" - username = arguments.username - auth_user = arguments.auth_user - must_be_admin = username != auth_user - validate_user(auth_user, must_be_admin=must_be_admin) + _validate_user(auth_user, auth_password, must_be_admin=must_be_admin) - password = read_password() - set_user_password(username, password) - set_samba_user(username, password) + _set_user_password(username, password) + _set_samba_user(username, password) -def get_admin_users(): - """Returns list of members in the admin group. - - Raises an error if the slapd service is not running. +def _get_admin_users(): + """Return list of members in the admin group. + Raise an error if the slapd service is not running. """ admin_users = [] @@ -420,8 +308,8 @@ def get_admin_users(): return admin_users -def get_group_users(groupname): - """Returns list of members in the group.""" +def _get_group_users(groupname): + """Return list of members in the group.""" try: process = _run(['ldapgid', '-P', groupname], stdout=subprocess.PIPE) except subprocess.CalledProcessError: @@ -435,10 +323,11 @@ def get_group_users(groupname): return users -def get_user_groups(username): - """Returns only the supplementary groups of the given user. +def _get_user_groups(username): + """Return only the supplementary groups of the given user. - Exclude the 'users' primary group from the returned list.""" + Exclude the 'users' primary group from the returned list. + """ process = _run(['ldapid', username], stdout=subprocess.PIPE, check=False) output = process.stdout.decode().strip() if output: @@ -460,121 +349,119 @@ def get_user_groups(username): return [] -def subcommand_get_user_groups(arguments): +@privileged +def get_user_groups(username: str) -> list[str]: """Return list of a given user's groups.""" - groups = get_user_groups(arguments.username) - if groups: - print(*groups, sep='\n') + return _get_user_groups(username) -def group_exists(groupname): +def _group_exists(groupname): """Return whether a group already exits.""" process = _run(['ldapgid', groupname], check=False) return process.returncode == 0 -def create_group(groupname): +def _create_group(groupname): """Add an LDAP group.""" - if not group_exists(groupname): + if not _group_exists(groupname): _run(['ldapaddgroup', groupname]) -def subcommand_create_group(arguments): +@privileged +def create_group(groupname: str): """Add an LDAP group.""" - create_group(arguments.groupname) - flush_cache() + _create_group(groupname) + _flush_cache() -def subcommand_rename_group(arguments): +@privileged +def rename_group(old_groupname: str, new_groupname: str): """Rename an LDAP group. Skip if the group to rename from doesn't exist. """ - old_groupname = arguments.old_groupname - new_groupname = arguments.new_groupname - if old_groupname == 'admin' or new_groupname == 'admin': - raise argparse.ArgumentTypeError('Can\'t rename the group "admin"') + raise ValueError('Can\'t rename the group "admin"') - if group_exists(old_groupname): + if _group_exists(old_groupname): _run(['ldaprenamegroup', old_groupname, new_groupname]) - flush_cache() + _flush_cache() -def subcommand_remove_group(arguments): +@privileged +def remove_group(groupname: str): """Remove an LDAP group.""" - groupname = arguments.groupname - if groupname == 'admin': - raise argparse.ArgumentTypeError("Can't remove the group 'admin'") + raise ValueError("Can't remove the group 'admin'") - if group_exists(groupname): + if _group_exists(groupname): _run(['ldapdeletegroup', groupname]) - flush_cache() + _flush_cache() -def add_user_to_group(username, groupname): +def _add_user_to_group(username, groupname): """Add an LDAP user to an LDAP group.""" - create_group(groupname) + _create_group(groupname) _run(['ldapaddusertogroup', username, groupname]) -def subcommand_add_user_to_group(arguments): +@privileged +def add_user_to_group(username: str, groupname: str, + auth_user: Optional[str] = None, + auth_password: Optional[str] = None): """Add an LDAP user to an LDAP group.""" - groupname = arguments.groupname - if groupname == 'admin': - validate_user(arguments.auth_user) + _validate_user(auth_user, auth_password) - add_user_to_group(arguments.username, groupname) - flush_cache() + _add_user_to_group(username, groupname) + _flush_cache() -def remove_user_from_group(username, groupname): +def _remove_user_from_group(username, groupname): """Remove an LDAP user from an LDAP group.""" _run(['ldapdeleteuserfromgroup', username, groupname]) -def subcommand_remove_user_from_group(arguments): +@privileged +def remove_user_from_group(username: str, groupname: str, auth_user: str, + auth_password: str): """Remove an LDAP user from an LDAP group.""" - username = arguments.username - groupname = arguments.groupname - if groupname == 'admin': - validate_user(arguments.auth_user) + _validate_user(auth_user, auth_password) - remove_user_from_group(username, groupname) - flush_cache() + _remove_user_from_group(username, groupname) + _flush_cache() if groupname == 'freedombox-share': - disconnect_samba_user(username) + _disconnect_samba_user(username) -def subcommand_get_group_users(arguments): +@privileged +def get_group_users(group_name: str) -> list[str]: """Get the list of users of an LDAP group.""" - for user in get_group_users(arguments.groupname): - print(user) + return _get_group_users(group_name) -def subcommand_set_user_status(arguments): +@privileged +def set_user_status(username: str, status: str, auth_user: str, + auth_password: str): """Set the status of the user.""" - username = arguments.username - status = arguments.status - auth_user = arguments.auth_user + if status not in ('active', 'inactive'): + raise ValueError('Invalid status') - validate_user(auth_user) + _validate_user(auth_user, auth_password) if status == 'active': flag = '-e' else: flag = '-d' - if username in get_samba_users(): + if username in _get_samba_users(): subprocess.check_call(['smbpasswd', flag, username]) if status == 'inactive': - disconnect_samba_user(username) + _disconnect_samba_user(username) -def flush_cache(): +def _flush_cache(): """Flush nscd and apache2 cache.""" _run(['nscd', '--invalidate=passwd']) _run(['nscd', '--invalidate=group']) @@ -587,17 +474,3 @@ def _run(arguments, check=True, **kwargs): kwargs['stdout'] = kwargs.get('stdout', subprocess.DEVNULL) kwargs['stderr'] = kwargs.get('stderr', subprocess.DEVNULL) return subprocess.run(arguments, env=env, check=check, **kwargs) - - -def main(): - """Parse arguments and perform all duties""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/users/templates/users_firstboot.html b/plinth/modules/users/templates/users_firstboot.html index 0802a12d9..0e3537f93 100644 --- a/plinth/modules/users/templates/users_firstboot.html +++ b/plinth/modules/users/templates/users_firstboot.html @@ -50,9 +50,9 @@ {% blocktrans trimmed %} Delete these accounts from command line and refresh the page to create an account that is usable with {{ box_name }}. On the command line run - the command 'echo "{password}" | /usr/share/plinth/actions/users - remove-user {username}'. If an account is already usable with - {{ box_name }}, skip this step. + the command "echo '{"args": ["USERNAME", "PASSWORD"], "kwargs": {}}' | + sudo /usr/share/plinth/actions/actions users remove_user". If an + account is already usable with {{ box_name }}, skip this step. {% endblocktrans %}

diff --git a/plinth/modules/users/tests/test_actions.py b/plinth/modules/users/tests/test_privileged.py similarity index 70% rename from plinth/modules/users/tests/test_actions.py rename to plinth/modules/users/tests/test_privileged.py index 832077d4e..54abf15e8 100644 --- a/plinth/modules/users/tests/test_actions.py +++ b/plinth/modules/users/tests/test_privileged.py @@ -1,4 +1,3 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later """ Test module to exercise user actions. @@ -6,7 +5,6 @@ Test module to exercise user actions. it is recommended to run this module with root privileges in a virtual machine. """ -import pathlib import random import re import string @@ -15,9 +13,15 @@ import subprocess import pytest from plinth import action_utils -from plinth.modules import security +from plinth.modules.security import privileged as security_privileged +from plinth.modules.users import privileged from plinth.tests import config as test_config +pytestmark = pytest.mark.usefixtures('mock_privileged') +privileged_modules_to_mock = [ + 'plinth.modules.users.privileged', 'plinth.modules.security.privileged' +] + _cleanup_users = None _cleanup_groups = None @@ -48,13 +52,6 @@ def _random_string(length=8): [random.choice(string.ascii_lowercase) for _ in range(length)]) -def _is_exit_zero(args): - """Return whether a command gave exit code zero""" - process = subprocess.run(args, stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, check=False) - return process.returncode == 0 - - def _get_password_hash(username): """Query and return the password hash of the given LDAP username""" query = [ @@ -90,21 +87,14 @@ def _try_login_to_ssh(username, password, returncode=0): return process.returncode == returncode -def _action_file(): - """Return the path to the 'users' actions file.""" - current_directory = pathlib.Path(__file__).parent - return str(current_directory / '..' / '..' / '..' / '..' / 'actions' / - 'users') - - @pytest.fixture(name='disable_restricted_access', autouse=True) def fixture_disable_restricted_access(needs_root, load_cfg): """Disable console login restrictions.""" - restricted_access = security.get_restricted_access_enabled() + restricted_access = security_privileged.get_restricted_access_enabled() if restricted_access: - security.set_restricted_access(False) + security_privileged.disable_restricted_access() yield - security.set_restricted_access(True) + security_privileged.enable_restricted_access() else: yield @@ -135,14 +125,7 @@ def fixture_auto_cleanup_users_groups(needs_root, load_cfg): pass for group in _cleanup_groups: - _delete_group(group) - - -def _call_action(arguments, check=True, **kwargs): - """Call the action script.""" - kwargs['stdout'] = kwargs.get('stdout', subprocess.PIPE) - kwargs['stderr'] = kwargs.get('stderr', subprocess.PIPE) - return subprocess.run([_action_file()] + arguments, check=check, **kwargs) + privileged.remove_group(group) def _create_user(username=None, groups=None): @@ -151,16 +134,13 @@ def _create_user(username=None, groups=None): password = username + '_passwd' admin_user, admin_password = _get_admin_user_password() - process_input = "{0}\n{1}".format(password, admin_password).encode() - _call_action(['create-user', '--auth-user', admin_user, username], - input=process_input) + privileged.create_user(username, password, admin_user, admin_password) if groups: for group in groups: admin_user, admin_password = _get_admin_user_password() - _call_action([ - 'add-user-to-group', '--auth-user', admin_user, username, group - ], input=admin_password.encode()) + privileged.add_user_to_group(username, group, admin_user, + admin_password) if group != 'admin': _cleanup_groups.add(group) @@ -170,11 +150,11 @@ def _create_user(username=None, groups=None): def _delete_user(username): """Utility to delete an LDAP and Samba user""" - process_input = None - if _get_group_users('admin') == [username]: + admin_password = None + if privileged.get_group_users('admin') == [username]: _, admin_password = _get_admin_user_password() - process_input = admin_password.encode() - _call_action(['remove-user', username], input=process_input) + + privileged.remove_user(username, admin_password) def _create_admin_if_does_not_exist(): @@ -186,8 +166,7 @@ def _create_admin_if_does_not_exist(): def _get_admin_user_password(): """Return an admin username and password.""" - - admin_users = _get_group_users('admin') + admin_users = privileged.get_group_users('admin') if not admin_users: return ('', '') @@ -205,36 +184,20 @@ def _rename_user(old_username, new_username=None): """Rename a user.""" new_username = new_username or _random_string() - _call_action(['rename-user', old_username, new_username]) + privileged.rename_user(old_username, new_username) _cleanup_users.remove(old_username) _cleanup_users.add(new_username) return new_username -def _get_group_users(group): - """Return the list of members in a group.""" - process = _call_action(['get-group-users', group]) - return process.stdout.decode().split() - - -def _get_user_groups(username): - """Return the list of groups for a user.""" - process = _call_action(['get-user-groups', username]) - return process.stdout.decode().split() - - def _create_group(groupname=None): groupname = groupname or _random_string() - _call_action(['create-group', groupname]) + privileged.create_group(groupname) if groupname != 'admin': _cleanup_groups.add(groupname) return groupname -def _delete_group(groupname): - _call_action(['remove-group', groupname]) - - def test_create_user(): """Test whether creating a new user works.""" _create_admin_if_does_not_exist() @@ -256,9 +219,8 @@ def test_change_user_password(): old_password_hash = _get_password_hash(username) new_password = 'pass $123' - process_input = "{0}\n{1}".format(new_password, admin_password).encode() - _call_action(['set-user-password', username, '--auth-user', admin_user], - input=process_input) + privileged.set_user_password(username, new_password, admin_user, + admin_password) new_password_hash = _get_password_hash(username) assert old_password_hash != new_password_hash @@ -277,9 +239,8 @@ def test_change_password_as_non_admin_user(): old_password_hash = _get_password_hash(username) new_password = 'pass $123' - process_input = "{0}\n{1}".format(new_password, old_password).encode() - _call_action(['set-user-password', username, '--auth-user', username], - input=process_input) + privileged.set_user_password(username, new_password, username, + old_password) new_password_hash = _get_password_hash(username) assert old_password_hash != new_password_hash @@ -298,11 +259,9 @@ def test_change_other_users_password_as_non_admin(): username2, _ = _create_user() new_password = 'pass $123' - process_input = "{0}\n{1}".format(new_password, password1).encode() with pytest.raises(subprocess.CalledProcessError): - _call_action( - ['set-user-password', username2, '--auth-user', username1], - input=process_input) + privileged.set_user_password(username2, new_password, username1, + password1) def test_set_password_for_non_existent_user(): @@ -313,11 +272,9 @@ def test_set_password_for_non_existent_user(): non_existent_user = _random_string() fake_password = _random_string() - process_input = "{0}\n{1}".format(fake_password, admin_password).encode() with pytest.raises(subprocess.CalledProcessError): - _call_action([ - 'set-user-password', non_existent_user, '--auth-user', admin_user - ], input=process_input) + privileged.set_user_password(non_existent_user, fake_password, + admin_user, admin_password) def test_rename_user(): @@ -325,15 +282,15 @@ def test_rename_user(): _create_admin_if_does_not_exist() old_username, password = _create_user(groups=['admin', _random_string()]) - old_groups = _get_user_groups(old_username) + old_groups = privileged.get_user_groups(old_username) new_username = _rename_user(old_username) assert _try_login_to_ssh(new_username, password) assert _try_login_to_ssh(old_username, password, returncode=5) assert old_username not in _get_samba_users() - new_groups = _get_user_groups(new_username) - old_users_groups = _get_user_groups(old_username) + new_groups = privileged.get_user_groups(new_username) + old_users_groups = privileged.get_user_groups(old_username) assert not old_users_groups # empty assert old_groups == new_groups @@ -357,11 +314,12 @@ def test_delete_user(): username, password = _create_user(groups=[_random_string()]) _delete_user(username) - groups_after = _get_user_groups(username) + groups_after = privileged.get_user_groups(username) assert not groups_after # User gets removed from all groups # User account cannot be found after deletion - assert not _is_exit_zero(['ldapid', username]) + with pytest.raises(subprocess.CalledProcessError): + subprocess.run(['ldapid', username], check=True) # Deleted user cannot login to ssh assert _try_login_to_ssh(username, password, returncode=5) @@ -373,7 +331,7 @@ def test_delete_non_existent_user(): """Deleting a non-existent user should fail.""" non_existent_user = _random_string() with pytest.raises(subprocess.CalledProcessError): - _call_action(['delete-user', non_existent_user]) + privileged.remove_user(non_existent_user) def test_groups(): @@ -381,16 +339,18 @@ def test_groups(): groupname = _random_string() _create_group(groupname) - assert _is_exit_zero(['ldapgid', groupname]) + with pytest.raises(subprocess.CalledProcessError): + subprocess.run(['ldapgid', groupname], check=True) # create-group is idempotent - assert _is_exit_zero([_action_file(), 'create-group', groupname]) + privileged.create_group(groupname) - _delete_group(groupname) - assert not _is_exit_zero(['ldapgid', groupname]) + privileged.remove_group(groupname) + with pytest.raises(subprocess.CalledProcessError): + subprocess.run(['ldapgid', groupname], check=True) # delete-group is idempotent - assert _is_exit_zero([_action_file(), 'remove-group', groupname]) + privileged.remove_group(groupname) def test_delete_admin_group_fails(): @@ -398,7 +358,8 @@ def test_delete_admin_group_fails(): groupname = 'admin' _create_group('admin') - assert not _is_exit_zero([_action_file(), 'remove-group', groupname]) + with pytest.raises(ValueError): + privileged.remove_group(groupname) def test_user_group_interactions(): @@ -408,48 +369,38 @@ def test_user_group_interactions(): group1 = _random_string() user1, _ = _create_user(groups=[group1]) - assert [group1] == _get_user_groups(user1) + assert [group1] == privileged.get_user_groups(user1) # add-user-to-group is not idempotent with pytest.raises(subprocess.CalledProcessError): - _call_action( - ['add-user-to-group', '--auth-user', admin_user, user1, group1], - input=admin_password.encode()) + privileged.add_user_to_group(user1, group1, admin_user, admin_password) # The same user can be added to other new groups group2 = _random_string() _create_group(group2) - _call_action( - ['add-user-to-group', '--auth-user', admin_user, user1, group2], - input=admin_password.encode()) + privileged.add_user_to_group(user1, group2, admin_user, admin_password) # Adding a user to a non-existent group creates the group group3 = _random_string() - _call_action( - ['add-user-to-group', '--auth-user', admin_user, user1, group3], - input=admin_password.encode()) + privileged.add_user_to_group(user1, group3, admin_user, admin_password) _cleanup_groups.add(group3) # The expected groups got created and the user is part of them. expected_groups = [group1, group2, group3] - assert expected_groups == _get_user_groups(user1) + assert expected_groups == privileged.get_user_groups(user1) # Remove user from group group_to_remove_from = random.choice(expected_groups) - _call_action([ - 'remove-user-from-group', '--auth-user', admin_user, user1, - group_to_remove_from - ], input=admin_password.encode()) + privileged.remove_user_from_group(user1, group_to_remove_from, admin_user, + admin_password) # User is no longer in the group that they're removed from expected_groups.remove(group_to_remove_from) - assert expected_groups == _get_user_groups(user1) + assert expected_groups == privileged.get_user_groups(user1) # User cannot be removed from a group that they're not part of random_group = _random_string() _create_group(random_group) with pytest.raises(subprocess.CalledProcessError): - _call_action([ - 'remove-user-from-group', '--auth-user', admin_user, user1, - random_group - ], input=admin_password.encode()) + privileged.remove_user_from_group(user1, random_group, admin_user, + admin_password) diff --git a/plinth/modules/users/tests/test_views.py b/plinth/modules/users/tests/test_views.py index 467604990..a622c7a58 100644 --- a/plinth/modules/users/tests/test_views.py +++ b/plinth/modules/users/tests/test_views.py @@ -31,18 +31,6 @@ def fixture_users_urls(): yield -def action_run(action, options, **kwargs): - """Action return values.""" - if action == 'users' and options == ['get-group-users', 'admin']: - return 'admin' - if action == 'ssh' and options[:2] == ['get-keys', '--username']: - return '' - if action == 'users' and options == ['get-user-groups', 'tester']: - return '' - - return None - - @pytest.fixture(autouse=True) def module_patch(): """Patch users module.""" @@ -54,8 +42,20 @@ def module_patch(): UsersAndGroups('users-and-groups-minetest', reserved_usernames=['debian-minetest']) - with patch('pwd.getpwall', return_value=pwd_users),\ - patch('plinth.actions.superuser_run', side_effect=action_run): + privileged = 'plinth.modules.users.privileged' + with patch('pwd.getpwall', return_value=pwd_users), \ + patch(f'{privileged}.create_user'), \ + patch(f'{privileged}.add_user_to_group'), \ + patch(f'{privileged}.set_user_password'), \ + patch(f'{privileged}.set_user_status'), \ + patch(f'{privileged}.rename_user'), \ + patch(f'{privileged}.get_group_users') as get_group_users, \ + patch('plinth.modules.ssh.privileged.set_keys'), \ + patch('plinth.modules.ssh.privileged.get_keys') as get_keys, \ + patch(f'{privileged}.get_user_groups') as get_user_groups: + get_group_users.return_value = ['admin'] + get_keys.return_value = [] + get_user_groups.return_value = [] yield diff --git a/plinth/modules/users/views.py b/plinth/modules/users/views.py index 7d25fe518..93a849ab3 100644 --- a/plinth/modules/users/views.py +++ b/plinth/modules/users/views.py @@ -1,4 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later +"""Django views for user app.""" import django.views.generic from django.contrib import messages @@ -13,13 +14,13 @@ from django.utils.translation import gettext_lazy from django.views.generic.edit import (CreateView, DeleteView, FormView, UpdateView) -from plinth import actions, translation -from plinth.errors import ActionError +import plinth.modules.ssh.privileged as ssh_privileged +from plinth import translation from plinth.modules import first_boot from plinth.utils import is_user_admin from plinth.views import AppView -from . import get_last_admin_user +from . import get_last_admin_user, privileged from .forms import (CreateUserForm, FirstBootForm, UserChangePasswordForm, UserUpdateForm) @@ -36,6 +37,7 @@ class ContextMixin: class UserCreate(ContextMixin, SuccessMessageMixin, CreateView): """View to create a new user.""" + form_class = CreateUserForm template_name = 'users_create.html' model = User @@ -56,6 +58,7 @@ class UserCreate(ContextMixin, SuccessMessageMixin, CreateView): class UserList(AppView, ContextMixin, django.views.generic.ListView): """View to list users.""" + model = User template_name = 'users_list.html' title = gettext_lazy('Users') @@ -69,6 +72,7 @@ class UserList(AppView, ContextMixin, django.views.generic.ListView): class UserUpdate(ContextMixin, SuccessMessageMixin, UpdateView): """View to update a user's details.""" + template_name = 'users_update.html' model = User form_class = UserUpdateForm @@ -95,11 +99,10 @@ class UserUpdate(ContextMixin, SuccessMessageMixin, UpdateView): """Return the data for initial form load.""" initial = super().get_initial() try: - ssh_keys = actions.superuser_run( - 'ssh', ['get-keys', '--username', self.object.username]) + ssh_keys = ssh_privileged.get_keys(self.object.username) initial['ssh_keys'] = ssh_keys.strip() initial['language'] = self.object.userprofile.language - except ActionError: + except Exception: pass return initial @@ -127,6 +130,7 @@ class UserDelete(ContextMixin, DeleteView): On GET, display a confirmation page. On POST, delete the user. """ + template_name = 'users_delete.html' model = User slug_field = 'username' @@ -134,6 +138,7 @@ class UserDelete(ContextMixin, DeleteView): title = gettext_lazy('Delete User') def __init__(self, *args, **kwargs): + """Initialize view, override delete method.""" super().__init__(*args, **kwargs) # Avoid a warning with Django 4.0 that delete member should not be @@ -147,9 +152,8 @@ class UserDelete(ContextMixin, DeleteView): messages.success(self.request, message) try: - actions.superuser_run('users', - ['remove-user', self.kwargs['slug']]) - except ActionError: + privileged.remove_user(self.kwargs['slug']) + except Exception: messages.error(self.request, _('Deleting LDAP user failed.')) def _delete(self, *args, **kwargs): @@ -175,6 +179,7 @@ class UserDelete(ContextMixin, DeleteView): class UserChangePassword(ContextMixin, SuccessMessageMixin, FormView): """View to change user password.""" + template_name = 'users_change_password.html' form_class = UserChangePasswordForm title = gettext_lazy('Change Password') @@ -214,8 +219,8 @@ class UserChangePassword(ContextMixin, SuccessMessageMixin, FormView): class FirstBootView(django.views.generic.CreateView): """Create user account and log the user in.""" - template_name = 'users_firstboot.html' + template_name = 'users_firstboot.html' form_class = FirstBootForm def dispatch(self, request, *args, **kwargs): @@ -229,15 +234,11 @@ class FirstBootView(django.views.generic.CreateView): def get_context_data(self, *args, **kwargs): """Add admin users to context data.""" context = super().get_context_data(*args, **kwargs) - - output = actions.superuser_run('users', ['get-group-users', 'admin']) - admin_users = output.strip().split('\n') if output.strip() else [] - context['admin_users'] = admin_users - + context['admin_users'] = privileged.get_group_users('admin') return context def get_form_kwargs(self): - """Make request available to the form (to insert messages)""" + """Make request available to the form (to insert messages).""" kwargs = super().get_form_kwargs() kwargs['request'] = self.request return kwargs diff --git a/actions/wireguard b/plinth/modules/wireguard/privileged.py old mode 100755 new mode 100644 similarity index 56% rename from actions/wireguard rename to plinth/modules/wireguard/privileged.py index 48ab2627f..34a61d0f0 --- a/actions/wireguard +++ b/plinth/modules/wireguard/privileged.py @@ -1,40 +1,27 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for WireGuard. -""" +"""Configuration helper for WireGuard.""" -import argparse -import json import subprocess +from plinth.actions import privileged + SERVER_INTERFACE = 'wg0' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('get-info', - help='Get info for each configured interface') - - subparsers.required = True - return parser.parse_args() - - -def _get_info(): +@privileged +def get_info() -> dict[str, dict]: """Return info for each configured interface.""" output = subprocess.check_output(['wg', 'show', 'all', 'dump']).decode().strip() lines = output.split('\n') - interfaces = {} + interfaces: dict[str, dict] = {} for line in lines: if not line: continue - fields = line.split() - fields = [field if field != '(none)' else None for field in fields] + fields = [ + field if field != '(none)' else None for field in line.split() + ] interface_name = fields[0] if interface_name in interfaces: latest_handshake = int(fields[5]) if int(fields[5]) else None @@ -61,21 +48,3 @@ def _get_info(): } return interfaces - - -def subcommand_get_info(_): - """Print info for each configured interface.""" - print(json.dumps(_get_info())) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/wireguard/utils.py b/plinth/modules/wireguard/utils.py index 2db3d19de..2d7b56c79 100644 --- a/plinth/modules/wireguard/utils.py +++ b/plinth/modules/wireguard/utils.py @@ -1,19 +1,17 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Utilities for managing WireGuard. -""" +"""Utilities for managing WireGuard.""" import datetime -import json import logging import subprocess import time -from plinth import actions from plinth import app as app_module from plinth import network from plinth.utils import import_from_gi +from . import privileged + nm = import_from_gi('NM', '1.0') IP_TEMPLATE = '10.84.0.{}' @@ -70,8 +68,7 @@ def get_nm_info(): def get_info(): """Return server and clients info.""" - output = actions.superuser_run('wireguard', ['get-info']) - status = json.loads(output) + status = privileged.get_info() nm_info = get_nm_info() diff --git a/plinth/modules/wordpress/__init__.py b/plinth/modules/wordpress/__init__.py index ac4f6519d..7b933a79c 100644 --- a/plinth/modules/wordpress/__init__.py +++ b/plinth/modules/wordpress/__init__.py @@ -1,11 +1,8 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure WordPress. -""" +"""FreedomBox app to configure WordPress.""" from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.daemon import Daemon @@ -13,11 +10,10 @@ from plinth.modules.apache.components import Webserver from plinth.modules.backups.components import BackupRestore from plinth.modules.firewall.components import Firewall from plinth.package import Packages +from plinth.privileged import service as service_privileged from plinth.utils import format_lazy -from . import manifest - -PUBLIC_ACCESS_FILE = '/etc/wordpress/is_public' +from . import manifest, privileged _description = [ _('WordPress is a popular way to create and manage websites and blogs. ' @@ -106,12 +102,12 @@ class WordPressApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) - actions.superuser_run('wordpress', ['setup']) + privileged.setup() if not old_version: self.enable() elif old_version < 3: # Apply changes to Apache configuration from v2 to v3. - actions.superuser_run('service', ['reload', 'apache2']) + service_privileged.reload('apache2') class WordPressBackupRestore(BackupRestore): @@ -120,9 +116,9 @@ class WordPressBackupRestore(BackupRestore): def backup_pre(self, packet): """Save database contents.""" super().backup_pre(packet) - actions.superuser_run('wordpress', ['dump-database']) + privileged.dump_database() def restore_post(self, packet): """Restore database contents.""" super().restore_post(packet) - actions.superuser_run('wordpress', ['restore-database']) + privileged.restore_database() diff --git a/plinth/modules/wordpress/data/etc/fail2ban/filter.d/wordpress-auth-freedombox.conf b/plinth/modules/wordpress/data/etc/fail2ban/filter.d/wordpress-auth-freedombox.conf deleted file mode 100644 index 6942f7502..000000000 --- a/plinth/modules/wordpress/data/etc/fail2ban/filter.d/wordpress-auth-freedombox.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Definition] -failregex = .* .* "POST /wordpress/wp-login.php HTTP/\S+" 200 diff --git a/plinth/modules/wordpress/data/etc/fail2ban/filter.d/wordpress-freedombox.conf b/plinth/modules/wordpress/data/etc/fail2ban/filter.d/wordpress-freedombox.conf new file mode 100644 index 000000000..44403b5eb --- /dev/null +++ b/plinth/modules/wordpress/data/etc/fail2ban/filter.d/wordpress-freedombox.conf @@ -0,0 +1,7 @@ +[INCLUDES] +before = common.conf + +[Definition] +_daemon = apache-access +prefregex = %(__prefix_line)s +failregex = \S+ - \S+ \[[^\]]*\] "POST /wordpress/wp-login.php HTTP/\S+" 200 diff --git a/plinth/modules/wordpress/data/etc/fail2ban/jail.d/wordpress-auth-freedombox.conf b/plinth/modules/wordpress/data/etc/fail2ban/jail.d/wordpress-auth-freedombox.conf deleted file mode 100644 index 6323016c5..000000000 --- a/plinth/modules/wordpress/data/etc/fail2ban/jail.d/wordpress-auth-freedombox.conf +++ /dev/null @@ -1,3 +0,0 @@ -[wordpress-auth-freedombox] -enabled = true -filter = wordpress-auth-freedombox diff --git a/plinth/modules/wordpress/data/etc/fail2ban/jail.d/wordpress-freedombox.conf b/plinth/modules/wordpress/data/etc/fail2ban/jail.d/wordpress-freedombox.conf new file mode 100644 index 000000000..d68d99506 --- /dev/null +++ b/plinth/modules/wordpress/data/etc/fail2ban/jail.d/wordpress-freedombox.conf @@ -0,0 +1,4 @@ +[wordpress-freedombox] +enabled = true +filter = wordpress-freedombox +journalmatch = SYSLOG_IDENTIFIER=apache-access diff --git a/actions/wordpress b/plinth/modules/wordpress/privileged.py old mode 100755 new mode 100644 similarity index 78% rename from actions/wordpress rename to plinth/modules/wordpress/privileged.py index ba96e8a8d..28ec93112 --- a/actions/wordpress +++ b/plinth/modules/wordpress/privileged.py @@ -1,10 +1,6 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for WordPress. -""" +"""Configuration helper for WordPress.""" -import argparse import os import pathlib import random @@ -15,7 +11,9 @@ import subprocess import augeas from plinth import action_utils -from plinth.modules.wordpress import PUBLIC_ACCESS_FILE +from plinth.actions import privileged + +PUBLIC_ACCESS_FILE = '/etc/wordpress/is_public' _config_file_path = pathlib.Path('/etc/wordpress/config-default.php') _static_config_file_path = pathlib.Path('/etc/wordpress/freedombox-static.php') @@ -27,26 +25,8 @@ DB_NAME = 'wordpress_fbx' DB_USER = 'wordpress_fbx' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('setup', - help='Create initial configuration and database') - subparsers.add_parser('dump-database', help='Dump database to file') - subparsers.add_parser('restore-database', - help='Restore database from file') - subparser = subparsers.add_parser('set-public', - help='Allow/disallow public access') - subparser.add_argument('--enable', choices=('True', 'False'), - help='Whether to enable or disable public acceess') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_setup(_): +@privileged +def setup(): """Create initial configuration and database for WordPress.""" if _db_file_path.exists() or _config_file_path.exists(): if _config_file_path.exists(): @@ -144,10 +124,11 @@ def _upgrade_config_file(): _config_file_path.write_text('\n'.join(lines), encoding='utf-8') -def subcommand_set_public(arguments): +@privileged +def set_public(enable: bool): """Allow/disallow public access.""" public_access_file = pathlib.Path(PUBLIC_ACCESS_FILE) - if arguments.enable == 'True': + if enable: public_access_file.touch() else: public_access_file.unlink(missing_ok=True) @@ -155,7 +136,13 @@ def subcommand_set_public(arguments): action_utils.service_reload('apache2') -def subcommand_dump_database(_): +def is_public() -> bool: + """Return whether public access is enabled.""" + return pathlib.Path(PUBLIC_ACCESS_FILE).exists() + + +@privileged +def dump_database(): """Dump database to file.""" _db_backup_file.parent.mkdir(parents=True, exist_ok=True) with _db_backup_file.open('w', encoding='utf-8') as file_handle: @@ -165,7 +152,8 @@ def subcommand_dump_database(_): ], stdout=file_handle, check=True) -def subcommand_restore_database(_): +@privileged +def restore_database(): """Restore database from file.""" with _db_backup_file.open('r', encoding='utf-8') as file_handle: subprocess.run(['mysql', '--user', 'root'], stdin=file_handle, @@ -189,16 +177,3 @@ def _load_augeas(): aug.load() return aug - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/wordpress/views.py b/plinth/modules/wordpress/views.py index 1387a05dd..049f515e5 100644 --- a/plinth/modules/wordpress/views.py +++ b/plinth/modules/wordpress/views.py @@ -1,28 +1,25 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring WordPress. -""" - -import pathlib +"""FreedomBox app for configuring WordPress.""" from django.contrib import messages from django.utils.translation import gettext as _ -from plinth import actions, views +from plinth import views -from . import PUBLIC_ACCESS_FILE +from . import privileged from .forms import WordPressForm class WordPressAppView(views.AppView): """Serve configuration page.""" + form_class = WordPressForm app_id = 'wordpress' def get_initial(self): """Get the current WordPress settings.""" status = super().get_initial() - status['is_public'] = pathlib.Path(PUBLIC_ACCESS_FILE).exists() + status['is_public'] = privileged.is_public() return status def form_valid(self, form): @@ -30,10 +27,7 @@ class WordPressAppView(views.AppView): old_status = form.initial new_status = form.cleaned_data if old_status['is_public'] != new_status['is_public']: - actions.superuser_run( - 'wordpress', - ['set-public', '--enable', - str(new_status['is_public'])]) + privileged.set_public(new_status['is_public']) messages.success(self.request, _('Configuration updated')) return super().form_valid(form) diff --git a/plinth/modules/zoph/__init__.py b/plinth/modules/zoph/__init__.py index 71ac501a1..7ec541429 100644 --- a/plinth/modules/zoph/__init__.py +++ b/plinth/modules/zoph/__init__.py @@ -1,14 +1,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app to configure Zoph web application -""" +"""FreedomBox app to configure Zoph web application.""" -import json import logging from django.utils.translation import gettext_lazy as _ -from plinth import actions from plinth import app as app_module from plinth import cfg, frontpage, menu from plinth.modules.apache.components import Webserver @@ -17,7 +13,7 @@ from plinth.modules.firewall.components import Firewall from plinth.package import Packages from plinth.utils import format_lazy -from . import manifest +from . import manifest, privileged logger = logging.getLogger(__name__) @@ -88,45 +84,21 @@ class ZophApp(app_module.App): def setup(self, old_version): """Install and configure the app.""" - actions.superuser_run('zoph', ['pre-install']) + privileged.pre_install() super().setup(old_version) - actions.superuser_run('zoph', ['setup']) + privileged.setup() self.enable() -def set_configuration(admin_user=None, enable_osm=None): - """Configure Zoph.""" - args = [] - if admin_user: - args += ['--admin-user', admin_user] - - if enable_osm is not None: - args += ['--enable-osm', str(enable_osm)] - - actions.superuser_run('zoph', ['set-configuration'] + args) - - -def is_configured(): - """Return whether the Zoph app is configured.""" - output = actions.superuser_run('zoph', ['is-configured']) - return output.strip() == 'true' - - -def get_configuration(): - """Return full configuration of Zoph.""" - configuration = actions.superuser_run('zoph', ['get-configuration']) - return json.loads(configuration) - - class ZophBackupRestore(BackupRestore): """Component to backup/restore Zoph database""" def backup_pre(self, packet): """Save database contents.""" super().backup_pre(packet) - actions.superuser_run('zoph', ['dump-database']) + privileged.dump_database() def restore_post(self, packet): """Restore database contents.""" super().restore_post(packet) - actions.superuser_run('zoph', ['restore-database']) + privileged.restore_database() diff --git a/actions/zoph b/plinth/modules/zoph/privileged.py old mode 100755 new mode 100644 similarity index 59% rename from actions/zoph rename to plinth/modules/zoph/privileged.py index ce8d7da61..eb555f44b --- a/actions/zoph +++ b/plinth/modules/zoph/privileged.py @@ -1,47 +1,21 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Configuration helper for Zoph server. -""" +"""Configuration helper for Zoph server.""" -import argparse import configparser -import json import os import re import subprocess +from typing import Optional from plinth import action_utils +from plinth.actions import privileged APACHE_CONF = '/etc/apache2/conf-available/zoph.conf' DB_BACKUP_FILE = '/var/lib/plinth/backups-data/zoph-database.sql' -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('pre-install', - help='Perform Zoph pre-install configuration') - subparser = subparsers.add_parser('setup', - help='Perform Zoph configuration setup') - subparsers.add_parser('get-configuration', - help='Return the current configuration') - subparser = subparsers.add_parser('set-configuration', - help='Configure zoph') - subparser.add_argument('--admin-user', help='Name of the admin user') - subparser.add_argument('--enable-osm', help='Enable OpenSteetMap maps') - subparsers.add_parser('is-configured', help='return true if configured') - subparsers.add_parser('dump-database', help='Dump database to file') - subparsers.add_parser('restore-database', - help='Restore database from file') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_pre_install(_): +@privileged +def pre_install(): """Preseed debconf values before packages are installed.""" action_utils.debconf_set_selections([ 'zoph zoph/dbconfig-install boolean true', @@ -49,7 +23,8 @@ def subcommand_pre_install(_): ]) -def subcommand_get_configuration(_): +@privileged +def get_configuration() -> dict[str, str]: """Return the current configuration.""" configuration = {} process = subprocess.run(['zoph', '--dump-config'], stdout=subprocess.PIPE, @@ -58,7 +33,7 @@ def subcommand_get_configuration(_): name, value = line.partition(':')[::2] configuration[name.strip()] = value[1:] - print(json.dumps(configuration)) + return configuration def _zoph_configure(key, value): @@ -66,7 +41,8 @@ def _zoph_configure(key, value): subprocess.run(['zoph', '--config', key, value], check=True) -def subcommand_setup(_): +@privileged +def setup(): """Setup Zoph configuration.""" _zoph_configure('import.enable', 'true') _zoph_configure('import.upload', 'true') @@ -88,19 +64,20 @@ def _get_db_name(): return config['zoph']['db_name'].strip('"') -def subcommand_set_configuration(arguments): +@privileged +def set_configuration(enable_osm: Optional[bool] = None, + admin_user: Optional[str] = None): """Setup Zoph Apache configuration.""" _zoph_configure('interface.user.remote', 'true') # Note that using OpenSteetmap as a mapping provider is a very nice # feature, but some people may regard its use as a privacy issue - if arguments.enable_osm: - value = 'osm' if arguments.enable_osm == 'True' else '' + if enable_osm is not None: + value = 'osm' if enable_osm else '' _zoph_configure('maps.provider', value) - if arguments.admin_user: + if admin_user: # Edit the database to rename the admin user to FreedomBox admin user. - admin_user = arguments.admin_user if not re.match(r'^[\w.@][\w.@-]+\Z', admin_user, flags=re.ASCII): # Check to avoid SQL injection raise ValueError('Invalid username') @@ -112,13 +89,16 @@ def subcommand_set_configuration(arguments): check=True) -def subcommand_is_configured(_): - """Print whether zoph app is configured.""" - subprocess.run(['zoph', '--get-config', 'interface.user.remote'], - check=True) +@privileged +def is_configured() -> bool: + """Return whether zoph app is configured.""" + process = subprocess.run(['zoph', '--get-config', 'interface.user.remote'], + stdout=subprocess.PIPE, check=True) + return process.stdout.decode().strip() == 'true' -def subcommand_dump_database(_): +@privileged +def dump_database(): """Dump database to file.""" db_name = _get_db_name() os.makedirs(os.path.dirname(DB_BACKUP_FILE), exist_ok=True) @@ -127,23 +107,11 @@ def subcommand_dump_database(_): check=True) -def subcommand_restore_database(_): +@privileged +def restore_database(): """Restore database from file.""" db_name = _get_db_name() subprocess.run(['mysqladmin', '--force', 'drop', db_name], check=False) subprocess.run(['mysqladmin', 'create', db_name], check=True) with open(DB_BACKUP_FILE, 'r', encoding='utf-8') as db_restore_file: subprocess.run(['mysql', db_name], stdin=db_restore_file, check=True) - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/modules/zoph/views.py b/plinth/modules/zoph/views.py index 485fa30b5..f7689de9e 100644 --- a/plinth/modules/zoph/views.py +++ b/plinth/modules/zoph/views.py @@ -1,7 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -FreedomBox app for configuring Zoph photo organiser. -""" +"""FreedomBox app for configuring Zoph photo organiser.""" import logging @@ -14,9 +12,8 @@ from django.views.generic import TemplateView from plinth import app as app_module from plinth import views -from plinth.errors import ActionError -from plinth.modules import zoph +from . import privileged from .forms import ZophForm logger = logging.getLogger(__name__) @@ -24,6 +21,7 @@ logger = logging.getLogger(__name__) class SetupView(TemplateView): """Show zoph setup page.""" + template_name = 'zoph-pre-setup.html' success_url = reverse_lazy('zoph:index') @@ -38,18 +36,19 @@ class SetupView(TemplateView): def post(self, _request, *args, **kwargs): """Handle form submission.""" admin_user = self.request.user.get_username() - zoph.set_configuration(admin_user=admin_user) + privileged.set_configuration(admin_user=admin_user) return HttpResponseRedirect(reverse_lazy('zoph:index')) class ZophAppView(views.AppView): """App configuration page.""" + form_class = ZophForm app_id = 'zoph' def dispatch(self, request, *args, **kwargs): """Redirect to setup page if setup is not done yet.""" - if not zoph.is_configured(): + if not privileged.is_configured(): return redirect('zoph:setup') return super().dispatch(request, *args, **kwargs) @@ -57,7 +56,7 @@ class ZophAppView(views.AppView): def get_initial(self): """Get the current settings from Zoph.""" status = super().get_initial() - config = zoph.get_configuration() + config = privileged.get_configuration() status['enable_osm'] = (config['maps.provider'] == 'osm') return status @@ -67,9 +66,10 @@ class ZophAppView(views.AppView): new_status = form.cleaned_data if old_status['enable_osm'] != new_status['enable_osm']: try: - zoph.set_configuration(enable_osm=new_status['enable_osm']) + privileged.set_configuration( + enable_osm=new_status['enable_osm']) messages.success(self.request, _('Configuration updated.')) - except ActionError: + except Exception: messages.error(self.request, _('An error occurred during configuration.')) diff --git a/plinth/package.py b/plinth/package.py index fe03981e7..c4e2a80dc 100644 --- a/plinth/package.py +++ b/plinth/package.py @@ -1,14 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Framework for installing and updating distribution packages -""" +"""Framework for installing and updating distribution packages.""" import enum -import json import logging import pathlib -import subprocess -import threading import time from typing import Optional, Union @@ -16,7 +11,8 @@ import apt.cache from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy -from plinth import actions, app +import plinth.privileged.packages as privileged +from plinth import app from plinth.errors import MissingPackageError from plinth.utils import format_lazy @@ -107,6 +103,7 @@ class Packages(app.FollowerComponent): class ConflictsAction(enum.Enum): """Action to take when a conflicting package is installed.""" + IGNORE = 'ignore' # Proceed as if there are no conflicts REMOVE = 'remove' # Remove the packages before installing the app @@ -307,74 +304,36 @@ class Transaction: """ try: - self._run_apt_command(['update']) - extra_arguments = [] - if skip_recommends: - extra_arguments.append('--skip-recommends') - - if force_configuration is not None: - extra_arguments.append( - '--force-configuration={}'.format(force_configuration)) - - if reinstall: - extra_arguments.append('--reinstall') - - if force_missing_configuration: - extra_arguments.append('--force-missing-configuration') - - self._run_apt_command(['install'] + extra_arguments + - [self.app_id] + self.package_names) - except subprocess.CalledProcessError as exception: + privileged.update() + kwargs = { + 'app_id': self.app_id, + 'packages': self.package_names, + 'skip_recommends': skip_recommends, + 'force_configuration': force_configuration, + 'reinstall': reinstall, + 'force_missing_configuration': force_missing_configuration + } + privileged.install(**kwargs) + except Exception as exception: logger.exception('Error installing package: %s', exception) raise def uninstall(self): """Run an apt-get transaction to uninstall given packages.""" try: - self._run_apt_command(['remove', self.app_id, '--packages'] + - self.package_names) - except subprocess.CalledProcessError as exception: + privileged.remove(app_id=self.app_id, packages=self.package_names) + except Exception as exception: logger.exception('Error uninstalling package: %s', exception) raise def refresh_package_lists(self): """Refresh apt package lists.""" try: - self._run_apt_command(['update']) - except subprocess.CalledProcessError as exception: + privileged.update() + except Exception as exception: logger.exception('Error updating package lists: %s', exception) raise - def _run_apt_command(self, arguments): - """Run apt-get and update progress.""" - self._reset_status() - - process = actions.superuser_run('packages', arguments, - run_in_background=True) - process.stdin.close() - - stdout_thread = threading.Thread(target=self._read_stdout, - args=(process, )) - stderr_thread = threading.Thread(target=self._read_stderr, - args=(process, )) - stdout_thread.start() - stderr_thread.start() - stdout_thread.join() - stderr_thread.join() - - return_code = process.wait() - if return_code != 0: - raise PackageException(_('Error running apt-get'), self.stderr) - - def _read_stdout(self, process): - """Read the stdout of the process and update progress.""" - for line in process.stdout: - self._parse_progress(line.decode()) - - def _read_stderr(self, process): - """Read the stderr of the process and store in buffer.""" - self.stderr = process.stderr.read().decode() - def _parse_progress(self, line): """Parse the apt-get process output line. @@ -461,10 +420,8 @@ def uninstall(package_names): def is_package_manager_busy(): """Return whether a package manager is running.""" try: - actions.superuser_run('packages', ['is-package-manager-busy'], - log_error=False) - return True - except actions.ActionError: + return privileged.is_package_manager_busy(_log_error=False) + except Exception: return False @@ -479,12 +436,8 @@ def filter_conffile_prompt_packages(packages): Information for each package includes: current_version, new_version and list of modified_conffiles. - """ - response = actions.superuser_run( - 'packages', - ['filter-conffile-packages', '--packages'] + list(packages)) - return json.loads(response) + return privileged.filter_conffile_packages(list(packages)) def packages_installed(candidates: Union[list, tuple]) -> list: diff --git a/plinth/privileged/__init__.py b/plinth/privileged/__init__.py new file mode 100644 index 000000000..14ade672b --- /dev/null +++ b/plinth/privileged/__init__.py @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""Package holding all the privileged actions outside of apps.""" + +from .packages import (filter_conffile_packages, install, + is_package_manager_busy, remove, update) +from .service import (disable, enable, is_enabled, is_running, mask, reload, + restart, start, stop, try_restart, unmask) + +__all__ = [ + 'filter_conffile_packages', 'install', 'is_package_manager_busy', 'remove', + 'update', 'disable', 'enable', 'is_enabled', 'is_running', 'mask', + 'reload', 'restart', 'start', 'stop', 'try_restart', 'unmask' +] diff --git a/actions/packages b/plinth/privileged/packages.py old mode 100755 new mode 100644 similarity index 74% rename from actions/packages rename to plinth/privileged/packages.py index 8ac12a27b..76f63a764 --- a/actions/packages +++ b/plinth/privileged/packages.py @@ -1,131 +1,97 @@ -#!/usr/bin/python3 # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Wrapper to handle package installation with apt-get. -""" +"""Wrapper to handle package installation with apt-get.""" -import argparse -import json import logging import os import subprocess -import sys from collections import defaultdict +from typing import Any, Optional import apt.cache import apt_inst import apt_pkg +from plinth import action_utils from plinth import app as app_module from plinth import module_loader -from plinth.action_utils import (apt_hold_freedombox, is_package_manager_busy, - run_apt_command) -from plinth.package import Packages +from plinth.action_utils import run_apt_command +from plinth.actions import privileged logger = logging.getLogger(__name__) -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('update', help='update the package lists') - - subparser = subparsers.add_parser('install', help='install packages') - subparser.add_argument( - '--skip-recommends', action='store_true', - help='whether to skip installing recommended packages') - subparser.add_argument( - '--force-configuration', choices=['new', 'old'], - help='force old/new configuration files during install') - subparser.add_argument( - '--reinstall', action='store_true', - help='force re-installation of package even if it is current') - subparser.add_argument( - '--force-missing-configuration', action='store_true', - help='force installation of missing configuration files') - subparser.add_argument( - 'app_id', help='ID of app for which package is being installed') - subparser.add_argument('packages', nargs='+', - help='list of packages to install') - - subparser = subparsers.add_parser('remove', help='remove the package(s)') - subparser.add_argument( - 'app_id', help='ID of app for which package is being uninstalled') - subparser.add_argument('--packages', required=True, - help='List of packages to remove', nargs='+') - - subparsers.add_parser('is-package-manager-busy', - help='Return whether package manager is busy') - subparser = subparsers.add_parser( - 'filter-conffile-packages', - help='Filter out packages that do not have pending conffile prompts') - subparser.add_argument('--packages', required=True, - help='List of packages to filter', nargs='+') - - subparsers.required = True - return parser.parse_args() - - -def subcommand_update(arguments): +@privileged +def update(): """Update apt package lists.""" - sys.exit(run_apt_command(['update'])) + returncode = run_apt_command(['update']) + if returncode: + raise RuntimeError( + f'Apt command failed with return code: {returncode}') -def subcommand_install(arguments): +@privileged +def install(app_id: str, packages: list[str], skip_recommends: bool = False, + force_configuration: Optional[str] = None, reinstall: bool = False, + force_missing_configuration: bool = False): """Install packages using apt-get.""" + if force_configuration not in ('old', 'new', None): + raise ValueError('Invalid value for force_configuration') + try: - _assert_managed_packages(arguments.app_id, arguments.packages) - except Exception as exception: - print('Access check failed:', exception, file=sys.stderr) - sys.exit(99) + _assert_managed_packages(app_id, packages) + except Exception: + raise PermissionError(f'Packages are not managed: {packages}') extra_arguments = [] - if arguments.skip_recommends: + if skip_recommends: extra_arguments.append('--no-install-recommends') - if arguments.force_configuration == 'old': + if force_configuration == 'old': extra_arguments += [ '-o', 'Dpkg::Options::=--force-confdef', '-o', 'Dpkg::Options::=--force-confold' ] - elif arguments.force_configuration == 'new': + elif force_configuration == 'new': extra_arguments += ['-o', 'Dpkg::Options::=--force-confnew'] - if arguments.reinstall: + if reinstall: extra_arguments.append('--reinstall') - if arguments.force_missing_configuration: + if force_missing_configuration: extra_arguments += ['-o', 'Dpkg::Options::=--force-confmiss'] subprocess.run(['dpkg', '--configure', '-a'], check=False) - with apt_hold_freedombox(): + with action_utils.apt_hold_freedombox(): run_apt_command(['--fix-broken', 'install']) - returncode = run_apt_command(['install'] + extra_arguments + - arguments.packages) + returncode = run_apt_command(['install'] + extra_arguments + packages) - sys.exit(returncode) + if returncode: + raise RuntimeError( + f'Apt command failed with return code: {returncode}') -def subcommand_remove(arguments): +@privileged +def remove(app_id: str, packages: list[str]): """Remove packages using apt-get.""" try: - _assert_managed_packages(arguments.app_id, arguments.packages) - except Exception as exception: - print('Access check failed:', exception, file=sys.stderr) - sys.exit(99) + _assert_managed_packages(app_id, packages) + except Exception: + raise PermissionError(f'Packages are not managed: {packages}') subprocess.run(['dpkg', '--configure', '-a'], check=False) - with apt_hold_freedombox(): + with action_utils.apt_hold_freedombox(): run_apt_command(['--fix-broken', 'install']) - returncode = run_apt_command(['remove'] + arguments.packages) + returncode = run_apt_command(['remove'] + packages) - sys.exit(returncode) + if returncode: + raise RuntimeError( + f'Apt command failed with return code: {returncode}') def _assert_managed_packages(app_id, packages): """Check that list of packages are in fact managed by module.""" + from plinth.package import Packages + module_loader.load_modules() app_module.apps_init() app = app_module.App.get(app_id) @@ -137,16 +103,18 @@ def _assert_managed_packages(app_id, packages): assert package in managed_packages -def subcommand_is_package_manager_busy(_): +@privileged +def is_package_manager_busy() -> bool: """Check whether package manager is busy. An exit code of zero indicates that package manager is busy. """ - if not is_package_manager_busy(): - sys.exit(-1) + return action_utils.is_package_manager_busy() -def subcommand_filter_conffile_packages(arguments): +@privileged +def filter_conffile_packages( + packages_list: list[str]) -> dict[str, dict[str, Any]]: """Return filtered list of packages which have pending conffile prompts. When considering which file needs a configuration file prompt, mimic the @@ -177,7 +145,7 @@ def subcommand_filter_conffile_packages(arguments): """ apt_pkg.init() # Read configuration that will be used later. - packages = set(arguments.packages) + packages = set(packages_list) status_hashes, current_versions = _get_conffile_hashes_from_status_file( packages) @@ -205,7 +173,7 @@ def subcommand_filter_conffile_packages(arguments): } packages_info[package] = package_info - print(json.dumps(packages_info)) + return packages_info def _get_modified_conffiles(status_hashes, mismatched_hashes, @@ -333,7 +301,7 @@ def _download_packages(packages): run_result = fetcher.run() if run_result != apt_pkg.Acquire.RESULT_CONTINUE: logger.error('Downloading packages failed.') - sys.exit(1) + raise RuntimeError('Downloading packages failed.') downloaded_files = [] for item in fetcher.items: @@ -409,16 +377,3 @@ def _get_conffile_hashes_from_downloaded_file(packages, downloaded_file, hashes[conffile] = md5sum return package_name, hashes, new_version - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/plinth/privileged/service.py b/plinth/privileged/service.py new file mode 100644 index 000000000..81f04238b --- /dev/null +++ b/plinth/privileged/service.py @@ -0,0 +1,118 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +"""List and handle system services.""" + +import os + +from plinth import action_utils +from plinth import app as app_module +from plinth import cfg, module_loader +from plinth.actions import privileged +from plinth.daemon import Daemon, RelatedDaemon + +cfg.read() +module_config_path = os.path.join(cfg.config_dir, 'modules-enabled') + + +@privileged +def start(service: str): + """Start a service.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_start(service) + + +@privileged +def stop(service: str): + """Stop a running service.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_stop(service) + + +@privileged +def enable(service: str): + """Enable a service so that it start on system boot.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_enable(service) + + +@privileged +def disable(service: str): + """Disable a service so that it does not start on system boot.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_disable(service) + + +@privileged +def restart(service: str): + """Restart a service.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_restart(service) + + +@privileged +def try_restart(service: str): + """Restart a service if it is running.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_try_restart(service) + + +@privileged +def reload(service: str): + """Reload a service.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_reload(service) + + +@privileged +def mask(service: str): + """Mask a service.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_mask(service) + + +@privileged +def unmask(service: str): + """Unmask a service.""" + _assert_service_is_managed_by_plinth(service) + action_utils.service_unmask(service) + + +@privileged +def is_enabled(service: str) -> bool: + """Return whether a service is enabled.""" + _assert_service_is_managed_by_plinth(service) + return action_utils.service_is_enabled(service) + + +@privileged +def is_running(service: str) -> bool: + """Return whether a service is running.""" + _assert_service_is_managed_by_plinth(service) + return action_utils.service_is_running(service) + + +def _get_managed_services(): + """Get a set of all services managed by FreedomBox.""" + services = set() + module_loader.load_modules() + app_module.apps_init() + for app in app_module.App.list(): + components = app.get_components_of_type(Daemon) + for component in components: + services.add(component.unit) + if component.alias: + services.add(component.alias) + + components = app.get_components_of_type(RelatedDaemon) + for component in components: + services.add(component.unit) + + return services + + +def _assert_service_is_managed_by_plinth(service_name): + managed_services = _get_managed_services() + if service_name not in managed_services: + msg = ("The service '%s' is not managed by FreedomBox. Access is only " + "permitted for services listed in the 'managed_services' " + "variable of any FreedomBox app.") % service_name + raise ValueError(msg) diff --git a/plinth/setup.py b/plinth/setup.py index 0a9449377..dddbe40bf 100644 --- a/plinth/setup.py +++ b/plinth/setup.py @@ -18,6 +18,7 @@ from plinth.signals import post_setup from . import operation as operation_module from . import package +from .privileged import packages as packages_privileged logger = logging.getLogger(__name__) @@ -418,7 +419,7 @@ class ForceUpgrader(): if _is_shutting_down: raise self.PermanentFailure('Service is shutting down') - if package.is_package_manager_busy(): + if packages_privileged.is_package_manager_busy(): raise self.TemporaryFailure('Package manager is busy') apps = self._get_list_of_apps_to_force_upgrade() diff --git a/plinth/templates/base.html b/plinth/templates/base.html index b431ca286..76db24170 100644 --- a/plinth/templates/base.html +++ b/plinth/templates/base.html @@ -26,9 +26,12 @@ + {% block title %} diff --git a/plinth/tests/functional/__init__.py b/plinth/tests/functional/__init__.py index 2d2660fe6..508c4980d 100644 --- a/plinth/tests/functional/__init__.py +++ b/plinth/tests/functional/__init__.py @@ -44,13 +44,14 @@ _site_url = { 'cockpit': '/_cockpit/', 'syncthing': '/syncthing/', 'rssbridge': '/rss-bridge/', + 'ttrss': '/tt-rss/', } _sys_modules = [ 'avahi', 'backups', 'bind', 'cockpit', 'config', 'datetime', 'diagnostics', 'dynamicdns', 'firewall', 'letsencrypt', 'names', 'networks', 'pagekite', - 'performance', 'power', 'security', 'snapshot', 'ssh', 'storage', - 'upgrades', 'users' + 'performance', 'power', 'privacy', 'security', 'snapshot', 'ssh', + 'storage', 'upgrades', 'users' ] diff --git a/plinth/tests/test_actions.py b/plinth/tests/test_actions.py index ca7335747..ed37a750e 100644 --- a/plinth/tests/test_actions.py +++ b/plinth/tests/test_actions.py @@ -9,191 +9,35 @@ description of the expectations. import json import os -import pathlib -import shutil -import tempfile -from unittest.mock import call, patch +import subprocess +from unittest.mock import Mock, call, patch -import apt_pkg import pytest from plinth import cfg -from plinth.actions import _log_command as log_command -from plinth.actions import privileged, run, superuser_run -from plinth.errors import ActionError +from plinth.actions import privileged -@pytest.fixture(autouse=True) -def actions_test_setup(load_cfg): - """Setup a temporary directory for testing actions. +@pytest.fixture(name='popen') +def fixture_popen(): + """A fixture to patch subprocess.Popen called by privileged action.""" - Copy system commands ``echo`` and ``id`` into actions directory during - testing. + with patch('subprocess.Popen') as popen: - """ - with tempfile.TemporaryDirectory() as tmp_directory: - old_actions_dir = cfg.actions_dir - cfg.actions_dir = str(tmp_directory) + def call_popen(command, **kwargs): + write_fd = int(command[8]) + if not isinstance(popen.called_with_write_fd, list): + popen.called_with_write_fd = [] - actions_dir = pathlib.Path(__file__).parent / '../../actions' - shutil.copy(str(actions_dir / 'packages'), str(tmp_directory)) - shutil.copy(str(actions_dir / 'test_path'), str(tmp_directory)) - shutil.copy('/bin/echo', str(tmp_directory)) - shutil.copy('/usr/bin/id', str(tmp_directory)) + popen.called_with_write_fd.append(write_fd) + os.write(write_fd, bytes(popen.return_value, encoding='utf-8')) + proc = Mock() + proc.communicate.return_value = ('', '') + proc.returncode = 0 + return proc - yield - cfg.actions_dir = old_actions_dir - - -def notest_run_as_root(): - """1. Privileged actions run as root. """ - assert superuser_run('id', ['-ur'])[0].strip() == '0' # user 0 is root - - -def test_breakout_actions_dir(): - """2. The actions directory can't be changed at run time. - - Can't currently be tested, as the actions directory is hardcoded. - """ - - -def test_breakout_up(): - """3A. Users can't call actions above the actions directory. - - Tests both a relative and a literal path. - """ - for action in ('../echo', '/bin/echo'): - with pytest.raises(ValueError): - run(action, ['hi']) - - -def test_breakout_down(): - """3B. Users can't call actions beneath the actions directory.""" - action = 'directory/echo' - with pytest.raises(ValueError): - superuser_run(action) - - -def test_breakout_actions(): - """3C. Actions can't be used to run other actions. - - If multiple actions are specified, bail out. - """ - # Counting is safer than actual badness. - actions = ('echo ""; echo $((1+1))', 'echo "" && echo $((1+1))', - 'echo "" || echo $((1+1))') - options = ('good', '') - - for action in actions: - for option in options: - with pytest.raises(ValueError): - run(action, [option]) - - -def test_breakout_option_string(): - """3D. Option strings can't be used to run other actions. - - Verify that shell control characters aren't interpreted. - """ - options = ('; echo hello', '&& echo hello', '|| echo hello', - '& echo hello', r'\; echo hello', '| echo hello', - r':;!&\/$%@`"~#*(){}[]|+=') - for option in options: - output = run('echo', [option]) - output = output.rstrip('\n') - assert option == output - - -def test_breakout_option_list(): - """3D. Option lists can't be used to run other actions. - - Verify that shell control characters aren't interpreted in - option lists. - """ - option_lists = ( - (';', 'echo', 'hello'), - ('&&', 'echo', 'hello'), - ('||', 'echo', 'hello'), - ('&', 'echo', 'hello'), - (r'\;', 'echo' - 'hello'), - ('|', 'echo', 'hello'), - ('', 'echo', '', 'hello'), # Empty option argument - tuple(r':;!&\/$%@`"~#*(){}[]|+=')) - for options in option_lists: - output = run('echo', options) - output = output.rstrip('\n') - expected_output = ' '.join(options) - assert output == expected_output - - -def test_multiple_options_and_output(): - """4. Multiple options can be provided as a list or as a tuple. - - 5. Output is returned from the command. - """ - options = '1 2 3 4 5 6 7 8 9' - - output = run('echo', options.split()) - output = output.rstrip('\n') - assert options == output - - output = run('echo', tuple(options.split())) - output = output.rstrip('\n') - assert options == output - - -@pytest.mark.usefixtures('needs_root') -def test_is_package_manager_busy(): - """Test the behavior of `is-package-manager-busy` in both locked and - unlocked states of the dpkg lock file.""" - - apt_pkg.init() # initialize apt_pkg module - - # In the locked state, the lsof command returns 0. - # Hence no error is thrown. - with apt_pkg.SystemLock(): - superuser_run('packages', ['is-package-manager-busy']) - - # In the unlocked state, the lsof command returns 1. - # An ActionError is raised in this case. - with pytest.raises(ActionError): - superuser_run('packages', ['is-package-manager-busy']) - - -@pytest.mark.usefixtures('develop_mode', 'needs_root') -def test_action_path(monkeypatch): - """Test that in development mode, python action scripts get the - correct PYTHONPATH""" - monkeypatch.setitem(os.environ, 'PYTHONPATH', '') - plinth_path = run('test_path').strip() - su_plinth_path = superuser_run('test_path').strip() - assert plinth_path.startswith(cfg.file_root) - assert plinth_path == su_plinth_path - - -@patch('plinth.actions.logger.info') -@pytest.mark.parametrize('cmd,message', [ - [['ls'], '$ ls'], - [['/bin/ls'], '$ ls'], - [['ls', 'a', 'b', 'c'], '$ ls a b c'], - [['ls', 'a b c'], "$ ls 'a b c'"], - [['ls', 'a;'], "$ ls 'a;'"], - [['sudo', 'ls'], '# ls'], - [['sudo', '-n', 'ls'], '# ls'], - [['sudo', '-u', 'tester', 'ls'], 'tester$ ls'], - [['sudo', 'key1=value1', 'key2=value2', 'ls'], '# ls'], - [[ - 'sudo', '-n', 'PYTHONPATH=/vagrant', '/vagrant/actions/ejabberd', - 'add-domain', '--domainname', 'freedombox.local' - ], '# ejabberd add-domain --domainname freedombox.local'], -]) -def test_log_command(logger, cmd, message): - """Test log messages for various action calls.""" - log_command(cmd) - logger.assert_called_once() - args = logger.call_args[0] - assert message == args[0] % args[1:] + popen.side_effect = call_popen + yield popen def test_privileged_properties(): @@ -247,41 +91,50 @@ def test_privileged_argument_annotation_check(): privileged(func_valid) -@patch('plinth.actions.superuser_run') -def test_privileged_method_call(superuser_run_): +@patch('plinth.actions._get_privileged_action_module_name') +def test_privileged_method_call(get_module_name, popen): """Test that privileged method calls the superuser action properly.""" def func_with_args(_a: int, _b: str, _c: int = 1, _d: str = 'dval', _e: str = 'eval'): return - superuser_run_.return_value = json.dumps({ - 'result': 'success', - 'return': 'bar' - }) + get_module_name.return_value = 'tests' + popen.return_value = json.dumps({'result': 'success', 'return': 'bar'}) wrapped_func = privileged(func_with_args) return_value = wrapped_func(1, 'bval', None, _d='dnewval') assert return_value == 'bar' input_ = {'args': [1, 'bval', None], 'kwargs': {'_d': 'dnewval'}} input_ = json.dumps(input_) - superuser_run_.assert_has_calls( - [call('actions', ['tests', 'func_with_args'], input=input_.encode())]) + write_fd = popen.called_with_write_fd[0] + close_from_fd = str(write_fd + 1) + popen.assert_has_calls([ + call([ + 'sudo', '--non-interactive', '--close-from', close_from_fd, + cfg.actions_dir + '/actions', 'tests', 'func_with_args', + '--write-fd', + str(write_fd) + ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, shell=False, pass_fds=[write_fd]) + ]) -@patch('plinth.actions.superuser_run') -def test_privileged_method_exceptions(superuser_run_): +@patch('plinth.actions._get_privileged_action_module_name') +def test_privileged_method_exceptions(get_module_name, popen): """Test that exceptions on privileged methods are return properly.""" def func_with_exception(): raise TypeError('type error') - superuser_run_.return_value = json.dumps({ + get_module_name.return_value = 'tests' + popen.return_value = json.dumps({ 'result': 'exception', 'exception': { 'module': 'builtins', 'name': 'TypeError', - 'args': ['type error'] + 'args': ['type error'], + 'traceback': [''] } }) wrapped_func = privileged(func_with_exception) diff --git a/plinth/tests/test_actions_actions.py b/plinth/tests/test_actions_actions.py index 9a5a84673..05c18b20c 100644 --- a/plinth/tests/test_actions_actions.py +++ b/plinth/tests/test_actions_actions.py @@ -22,11 +22,6 @@ def test_call_syntax_checks(getuid, get_module_import_path, import_module, """Test that calling a method results in proper syntax checks.""" call = actions_module._call - # Test for root permissions - getuid.return_value = 1000 - with pytest.raises(PermissionError): - call('x-module', 'x-action', {}) - # Module name validation getuid.return_value = 0 with pytest.raises(SyntaxError, match='Invalid module name'): @@ -77,14 +72,13 @@ def test_call_syntax_checks(getuid, get_module_import_path, import_module, setattr(module, 'func', exception_func) return_value = call('test-module', 'func', {'args': [], 'kwargs': {}}) - assert return_value == { - 'result': 'exception', - 'exception': { - 'module': 'builtins', - 'name': 'RuntimeError', - 'args': ('foo exception', ) - } - } + assert return_value['result'] == 'exception' + assert return_value['exception']['module'] == 'builtins' + assert return_value['exception']['name'] == 'RuntimeError' + assert return_value['exception']['args'] == ('foo exception', ) + assert isinstance(return_value['exception']['traceback'], list) + for line in return_value['exception']['traceback']: + assert isinstance(line, str) def test_assert_valid_arguments(actions_module): diff --git a/plinth/tests/test_daemon.py b/plinth/tests/test_daemon.py index c28d73db2..8b68f5796 100644 --- a/plinth/tests/test_daemon.py +++ b/plinth/tests/test_daemon.py @@ -4,14 +4,23 @@ Test module for component managing system daemons and other systemd units. """ import socket +import subprocess from unittest.mock import Mock, call, patch import pytest -from plinth.app import App, FollowerComponent +from plinth.app import App, FollowerComponent, Info from plinth.daemon import (Daemon, RelatedDaemon, app_is_running, diagnose_netcat, diagnose_port_listening) +privileged_modules_to_mock = ['plinth.privileged.service'] + + +class AppTest(App): + """Test application that contains a daemon.""" + + app_id = 'test-app' + @pytest.fixture(name='daemon') def fixture_daemon(): @@ -19,6 +28,17 @@ def fixture_daemon(): return Daemon('test-daemon', 'test-unit') +@pytest.fixture(name='app_list') +def fixture_app_list(daemon): + """A list of apps on which tests are to be run.""" + app1 = AppTest() + app1.add(Info('test-app', 1)) + app1.add(daemon) + with patch('plinth.app.App.list') as app_list: + app_list.return_value = [app1] + yield app_list + + def test_initialization(): """Test that component is initialized properly.""" with pytest.raises(ValueError): @@ -56,25 +76,51 @@ def test_is_enabled(service_is_enabled, daemon): service_is_enabled.assert_has_calls([call('test-unit', strict_check=True)]) -@patch('plinth.actions.superuser_run') -def test_enable(superuser_run, daemon): +@patch('subprocess.run') +@patch('subprocess.call') +def test_enable(subprocess_call, subprocess_run, app_list, mock_privileged, + daemon): """Test that enabling the daemon works.""" daemon.enable() - superuser_run.assert_has_calls([call('service', ['enable', 'test-unit'])]) + subprocess_call.assert_has_calls( + [call(['systemctl', 'enable', 'test-unit'])]) + subprocess_run.assert_any_call(['systemctl', 'start', 'test-unit'], + stdout=subprocess.DEVNULL, check=False) + subprocess_call.reset_mock() daemon.alias = 'test-unit-2' daemon.enable() - superuser_run.assert_has_calls([ - call('service', ['enable', 'test-unit']), - call('service', ['enable', 'test-unit-2']) + subprocess_call.assert_has_calls([ + call(['systemctl', 'enable', 'test-unit']), + call(['systemctl', 'enable', 'test-unit-2']) ]) + subprocess_run.assert_any_call(['systemctl', 'start', 'test-unit'], + stdout=subprocess.DEVNULL, check=False) + subprocess_run.assert_any_call(['systemctl', 'start', 'test-unit-2'], + stdout=subprocess.DEVNULL, check=False) -@patch('plinth.actions.superuser_run') -def test_disable(superuser_run, daemon): +@patch('subprocess.run') +@patch('subprocess.call') +def test_disable(subprocess_call, subprocess_run, mock_privileged, daemon): """Test that disabling the daemon works.""" daemon.disable() - superuser_run.assert_has_calls([call('service', ['disable', 'test-unit'])]) + subprocess_call.assert_has_calls( + [call(['systemctl', 'disable', 'test-unit'])]) + subprocess_run.assert_any_call(['systemctl', 'stop', 'test-unit'], + stdout=subprocess.DEVNULL, check=False) + + subprocess_call.reset_mock() + daemon.alias = 'test-unit-2' + daemon.disable() + subprocess_call.assert_has_calls([ + call(['systemctl', 'disable', 'test-unit']), + call(['systemctl', 'disable', 'test-unit-2']) + ]) + subprocess_run.assert_any_call(['systemctl', 'stop', 'test-unit'], + stdout=subprocess.DEVNULL, check=False) + subprocess_run.assert_any_call(['systemctl', 'stop', 'test-unit-2'], + stdout=subprocess.DEVNULL, check=False) @patch('plinth.action_utils.service_is_running') diff --git a/plinth/tests/test_frontpage.py b/plinth/tests/test_frontpage.py index f09d84569..df6005ce1 100644 --- a/plinth/tests/test_frontpage.py +++ b/plinth/tests/test_frontpage.py @@ -109,33 +109,33 @@ def test_shortcut_list_web_apps_only(common_shortcuts): assert return_list == [cuts[0], cuts[1], cuts[2]] -@patch('plinth.actions.superuser_run') -def test_shortcut_list_with_username(superuser_run, common_shortcuts): +@patch('plinth.modules.users.privileged.get_user_groups') +def test_shortcut_list_with_username(get_user_groups, common_shortcuts): """Test listing for particular users.""" cuts = common_shortcuts return_list = Shortcut.list() assert return_list == [cuts[0], cuts[1], cuts[2], cuts[3]] - superuser_run.return_value = 'admin' + get_user_groups.return_value = ['admin'] return_list = Shortcut.list(username='admin') assert return_list == [cuts[0], cuts[1], cuts[2], cuts[3]] - superuser_run.return_value = 'group1' + get_user_groups.return_value = ['group1'] return_list = Shortcut.list(username='user1') assert return_list == [cuts[0], cuts[1], cuts[3]] - superuser_run.return_value = 'group1\ngroup2' + get_user_groups.return_value = ['group1', 'group2'] return_list = Shortcut.list(username='user2') assert return_list == [cuts[0], cuts[1], cuts[2], cuts[3]] cut = Shortcut('group2-web-app-component-1', 'name5', 'short2', url='url4', login_required=False, allowed_groups=['group3']) - superuser_run.return_value = 'group3' + get_user_groups.return_value = ['group3'] return_list = Shortcut.list(username='user3') assert return_list == [cuts[0], cuts[3], cut] - superuser_run.return_value = 'group4' + get_user_groups.return_value = ['group4'] return_list = Shortcut.list(username='user4') assert return_list == [cuts[0], cuts[3], cut] diff --git a/pyproject.toml b/pyproject.toml index 5ef7e8f2f..0af5e8616 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,7 @@ markers = [ "openvpn", "pagekite", "performance", + "privacy", "privoxy", "quassel", "radicale", diff --git a/vagrant-scripts/plinth-user-permissions.py b/vagrant-scripts/plinth-user-permissions.py index e081446c3..64ade9b4e 100755 --- a/vagrant-scripts/plinth-user-permissions.py +++ b/vagrant-scripts/plinth-user-permissions.py @@ -1,24 +1,16 @@ #!/usr/bin/python3 # -*- mode: python -*- # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Set required permissions for user "plinth" to run plinth in the development -environment. -""" +"""Set required permissions for user "plinth" to run plinth in dev setup.""" -import augeas +import pathlib -sudoers_file = '/etc/sudoers.d/plinth' -aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD + - augeas.Augeas.NO_MODL_AUTOLOAD) +content = ''' +Cmnd_Alias FREEDOMBOX_ACTION_DEV = /usr/share/plinth/actions/actions, /vagrant/actions/actions +Defaults!FREEDOMBOX_ACTION_DEV closefrom_override +plinth ALL=(ALL:ALL) NOPASSWD:SETENV : FREEDOMBOX_ACTION_DEV +fbx ALL=(ALL:ALL) NOPASSWD : ALL +''' -# lens for shell-script config file -aug.set('/augeas/load/Shellvars/lens', 'Sudoers.lns') -aug.set('/augeas/load/Shellvars/incl[last() + 1]', sudoers_file) -aug.load() - -aug.set('/files{}/spec[1]/host_group/command[2]'.format(sudoers_file), - '/vagrant/actions/*') -aug.set('/files{}/spec[1]/host_group/command[1]/tag[2]'.format(sudoers_file), - 'SETENV') -aug.save() +sudoers_file = pathlib.Path('/etc/sudoers.d/01-freedombox-development') +sudoers_file.write_text(content)