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"
@@ -1650,19 +1643,19 @@ msgid ""
"any 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"
@@ -1650,19 +1643,19 @@ msgid ""
"any 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"
@@ -1755,19 +1748,19 @@ msgstr ""
"до 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 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"
@@ -1650,19 +1643,19 @@ msgid ""
"any 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"
"em>. 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 client"
@@ -1825,7 +1818,7 @@ msgstr ""
"přistupovat kterýkoli už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"
"em>."
-#: 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"
@@ -1863,19 +1856,19 @@ msgstr ""
"bruges af enhver bruger med adgang til {box_name}"
"a>."
-#: 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"
"a> 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"
@@ -1864,7 +1857,7 @@ msgstr ""
"aktiviert, kann ejabberd von jedem 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"
@@ -1647,19 +1640,19 @@ msgid ""
"any 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"
@@ -1917,19 +1909,19 @@ msgstr ""
"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 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 client"
@@ -1843,7 +1836,7 @@ msgstr ""
"\">cliente 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"
@@ -1862,19 +1853,19 @@ msgid ""
"any 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 client"
@@ -1879,7 +1872,7 @@ msgstr ""
"accessible par tout utilisateur 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"
"a>."
-#: 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"
"a> 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"
"em> 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"
@@ -1653,19 +1646,19 @@ msgid ""
"any 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"
@@ -1850,7 +1843,7 @@ msgstr ""
"bármely 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)"
"a>."
-#: 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 client"
@@ -1859,7 +1852,7 @@ msgstr ""
"\" target=\"_blank\">Klien 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"
@@ -1835,19 +1828,19 @@ msgstr ""
"accedere a ejabberd 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"
@@ -1649,19 +1642,19 @@ msgid ""
"any 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"
@@ -1649,19 +1642,19 @@ msgid ""
"any 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"
@@ -1651,19 +1644,19 @@ msgid ""
"any 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"
@@ -1650,19 +1643,19 @@ msgid ""
"any 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 client"
@@ -1879,19 +1872,19 @@ msgstr ""
"tilgjengelig for enhver bruker 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"
"a>."
-#: 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 ejabberd"
"a>moeten 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 client"
@@ -1845,7 +1838,7 @@ msgstr ""
"kan elke gebruiker 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"
"a> 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 client"
@@ -1846,19 +1839,19 @@ msgstr ""
"clients' target='_blank'>klienta 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"
@@ -1752,19 +1745,19 @@ msgid ""
"any 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"
@@ -1841,7 +1832,7 @@ msgstr ""
"\"> 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"
"a>."
-#: 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"
@@ -1649,19 +1642,19 @@ msgid ""
"any 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"
@@ -1805,19 +1798,19 @@ msgid ""
"any 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"
@@ -1866,7 +1838,7 @@ msgstr ""
"aktivizohet, ejabberd mund të përdoret nga cilido përdorues 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"
"a>."
-#: 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"
"a>."
-#: 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"
@@ -1736,19 +1729,19 @@ msgid ""
"any 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"
@@ -1838,7 +1827,7 @@ msgstr ""
"nås av alla användare med en {box_name} inloggning"
"a>."
-#: 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"
"a> 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"
@@ -1648,19 +1641,19 @@ msgid ""
"any 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"
"a> 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"
@@ -1789,7 +1782,7 @@ msgstr ""
"XMPP క్లయింట్. ప్రారంభించబడినప్పుడు, 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 ""
"శోధన బటన్పై క్లిక్ చేయడం ద్వారా ఇప్పటికే ఉన్న క్యాలెండర్లు మరియు చిరునామా పుస్తకాలు జాబితా చేయబడతాయి."
"your.freedombox.address>"
-#: 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"
@@ -1828,7 +1821,7 @@ msgstr ""
"Etkinleştirildiğinde, ejabberd'e {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"
"a> 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"
"a> потрібно налаштовувати з урахуванням деталей наведених тут."
-#: 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"
@@ -1815,7 +1831,7 @@ msgstr ""
"\"_blank\">клієнт 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"
+"a>)."
#: 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"
@@ -1855,19 +1848,19 @@ msgid ""
"any 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"
"a> 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"
@@ -1747,7 +1740,7 @@ msgstr ""
"a>。启用后,任何有 {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"
@@ -1736,19 +1729,19 @@ msgid ""
"any 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 群組的 任何使用者"
"a>存取。"
-#: 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' %}
+
+
+
+
{% trans "Service/Port" %}
+
{% trans "Status" %}
+
-
- {% 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 %}
-
- {% 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 %}
-
-
-
+ {% 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 %}
-
+ {% 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 %}
-
+
-
- {% 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)