freedombox Debian release 21.9

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmFF9NoACgkQd8DHXntl
 CAglCQ/9FykcYeFj+TgP4xIEIIMgnVyFaLpzvbCt/QwTZVCDiYwRxIAlbxzTEjIl
 XHRPlhXg4vY57yEgB2NGqatXD0JuvQKM9dWx8Kc9yfKI+pQquZqrWWxQ3ALi3WH2
 Glev8GA85r2BbeegNuxy1k+Oq1ceIcEmOP+ipUptzrJk8LPPmG/WQoqn4lr5SB9+
 rsusf/wTzLglXtVXgDjAbmmtmd7xT5bHUQ83uX4mSRh7pXauVbrVR4onwibonqXi
 lpvAtg5fOma36BdMgtIX4qI+y7AlEvVzdcMaygGup8oemLVE5Sd179thjSyEeEYL
 FKt80OQoeHW4G3QvOvRZlG3vseb4xsFlfOUJGjF3lBjzaMngMoGls1E2zu5J3KmX
 csup5MCXOw4dh468hY1dyhk8GQ1mzHTw/z2iWPk0VTT92mxhEZ2Exb45LZ8PXoKR
 HGBRhpPdtpYXVQ9LHOcJZWgWODx/cngQ2LJGOsEXdaEEwPpzA7VKz65NNfz0x8s0
 CyXbYcIihzfdCWGAs9i787rrwupOPGldrlPhbuZxMjupcjnCEg+PIh3g7trpDhh/
 D6/b7J5eieWV3e6SHQdIXjCgSb8S8BIqPDIyAFduwg1RK8OFpEZoONtcam34xilm
 5xboI0lWelbWQA95drhyCUOI8oZDjKDrUHOb8hmYDTvdl9Y/gPA=
 =+qRd
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmFKENMACgkQd8DHXntl
 CAgZQxAA0z7e+4fu8KdEE0I8EWgUtdgXUWHWmENv3mOlYCRKRDWdy+GH5bDeS5TX
 z/ae+k/L60UYKQbyBJQQGXTxfGyvRlZ6EuAkhQiP7SYM198ogECzbn65SziBmno0
 IKJpmaOatxWuJXu2ID1COzxdS8O2+CNjAtHnMh9luoOA1txIjxEaSmp02z9btSJD
 H5MB0YPLwZoXBtJnsXhHPonWBfXUvV8W1uOGQY9gnRVbAoX/UGQfUuoMgk4zTih8
 gP8G2Sa7u7zZZtT+AVTuteWlpFZprhCdcNS8bu6789O7Hrt7RdtWWz0JyZ5IgpiE
 JPECgiiCrF9m/RpFGbFtgth3nxt19qcFGvARNWSx93NcgSzJj8XWkYaO6o+lEh2R
 6F74WVYrIVKncSgae1EE2ym1Xj+88gcLbzVyHcbG28IK5g2jssO4QHZXENoixGmA
 V/TLFhlZ+tVs+J5NrtRK5DICyPLuNMeUr0P6xkfuVPrc23htHAZe0kDc6y0wbpRA
 jYeBUiZQYKY2Um2t8UzJaOCNiC67ILF9Ul0bBSQq+nlauY3Y6uHmZop+GkIF/eX9
 pInZXHveZFYaxgr3mNiWH051+LtVxVIW7wvJP/QZFhsvhH+rpS3SqIebZ7bfTf0A
 WC8i0T6O7PwH9yP4uH4WgPa52j2sRIha0o5jQ0UQhjVknTUGFZo=
 =mx6f
 -----END PGP SIGNATURE-----

Merge tag 'v21.9' into debian/bullseye-backports

freedombox Debian release 21.9

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
James Valleroy 2021-09-21 13:05:21 -04:00
commit 3f8d529389
99 changed files with 2354 additions and 1611 deletions

View File

@ -115,10 +115,9 @@ directory:
guest$ cd /freedombox
```
Run the development version of FreedomBox Service (Plinth) from your source
directory in the container using the following command. This command
continuously deploys your code changes into the container providing a
quick feedback cycle during development.
Run the development version of FreedomBox Service in the container using the
following command. This command continuously deploys your code changes into the
container providing a quick feedback cycle during development.
```bash
guest$ freedombox-develop

View File

@ -126,6 +126,13 @@ def subcommand_setup(arguments):
# Disable /server-status page to avoid leaking private info.
webserver.disable('status', kind='module')
# Enable HTTP/2 protocol
webserver.enable('http2', kind='module')
# Enable shared object cache needed for OSCP stapling. Needed by
# mod_ssl.
webserver.enable('socache_shmcb', kind='module')
# switch to mod_ssl from mod_gnutls
webserver.disable('gnutls', kind='module')
webserver.enable('ssl', kind='module')

View File

@ -130,7 +130,7 @@ from urllib.request import urlopen
URLS = {
'stable': 'https://ftp.freedombox.org/pub/freedombox/hardware/'
'amd64/stable/freedombox-stable-free_buster_all-amd64.img.xz',
'amd64/bullseye/freedombox-bullseye-free_all-amd64.img.xz',
'testing': 'https://ftp.freedombox.org/pub/freedombox/hardware/'
'amd64/testing/freedombox-testing-free_dev_all-amd64.img.xz',
'unstable': 'https://ftp.freedombox.org/pub/freedombox/hardware/'
@ -164,7 +164,7 @@ sudo apt-mark unhold freedombox
sudo DEBIAN_FRONTEND=noninteractive apt-get install --yes ncurses-term \
sshpass bash-completion
echo 'alias freedombox-develop="sudo -u plinth /freedombox/run --develop"' \
echo 'alias freedombox-develop="cd /freedombox; sudo -u plinth /freedombox/run --develop"' \
>> /home/fbx/.bashrc
# Make some pytest related files and directories writable to the fbx user
@ -812,8 +812,16 @@ def _destroy(distribution):
connection_name = f'fbx-{distribution}-shared'
logger.info('Removing Network Manager connection %s', connection_name)
subprocess.run(['sudo', 'nmcli', 'connection', 'delete', connection_name],
stdout=subprocess.DEVNULL)
result = subprocess.run(
['sudo', 'nmcli', 'connection', 'delete', connection_name],
capture_output=True)
if result.returncode not in (0, 10):
# nmcli failed and not due to 'Connection, device, or access point does
# not exist.' See
# https://developer-old.gnome.org/NetworkManager/stable/nmcli.html
logger.error('nmcli returned code %d', result.returncode)
logger.error('Error message:\n%s', result.stderr.decode())
logger.error('Output:\n%s', result.stdout.decode())
logger.info('Keeping downloaded image: %s',
_get_compressed_image_path(distribution))
@ -920,9 +928,8 @@ def _get_latest_image_timestamp(distribution):
url = URLS[distribution]
response = urlopen(url[0:url.rindex('/')])
page_contents = response.read().decode()
str_time = re.findall(r'\d{2}-[A-Z][a-z]{2}-\d{4} \d{2}:\d{2}',
page_contents)[0]
return datetime.datetime.strptime(str_time, '%d-%b-%Y %H:%M').timestamp()
str_time = re.findall(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}', page_contents)[0]
return datetime.datetime.strptime(str_time, '%Y-%m-%d %H:%M').timestamp()
def _is_update_required(distribution):

View File

@ -1,25 +1,6 @@
<Macro FreedomBoxTLSSiteMacro $domain>
# mod_gnutls default options. See /etc/apache2/site-available/default-tls.conf
<IfModule mod_gnutls.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
ServerName $domain
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
GnuTLSEnable On
# Automatically obtained certificates from Let's Encrypt
GnuTLSCertificateFile /etc/letsencrypt/live/$domain/fullchain.pem
GnuTLSKeyFile /etc/letsencrypt/live/$domain/privkey.pem
# See http://www.outoforder.cc/projects/apache/mod_gnutls/docs/#GnuTLSPriorities
GnuTLSPriorities NORMAL
</VirtualHost>
</IfModule>
# mod_ssl default options. See /etc/apache2/site-available/default-ssl.conf
# mod_ssl default options. See /etc/apache2/sites-available/default-ssl.conf
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
@ -30,6 +11,13 @@
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
# Disable TLS1.1 and below. Client support: Firefox: 27, Android:
# 4.4.2, Chrome: 31, Edge: 12, IE: 11 (Win7), Java: 8u31, OpenSSL:
# 1.0.1, Opera: 20, Safari: 9. See:
# https://wiki.mozilla.org/Security/Server_Side_TLS
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
# Automatically obtained certificates from Let's Encrypt
SSLCertificateFile /etc/letsencrypt/live/$domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/$domain/privkey.pem

View File

@ -1,3 +1,36 @@
## SPDX-License-Identifier: AGPL-3.0-or-later
##
## DO NOT EDIT. If you do, FreedomBox will not automatically upgrade.
##
## Apache configuration managed by FreedomBox. If customization is needed,
## create a new configuration file with higher priority and override directives.
##
##
## TLS configuration as recommended by Mozilla's SSL Configuration Generator
## with 'Intermediate' configuration. See:
## https://wiki.mozilla.org/Security/Server_Side_TLS
##
<IfModule mod_ssl.c>
# Disable ciphers that are weak or without forward secrecy.
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
# Allow client to choose ciphers as they will know best if they have support
# for hardware-accelerated AES.
SSLHonorCipherOrder off
# TLS session tickets (RFC 5077) require restarting web server with an
# appropriate frequency. See:
# https://httpd.apache.org/docs/current/mod/mod_ssl.html#sslsessiontickets
SSLSessionTickets off
# Send OCSP responses to the client and reduce their round trips.
<IfModule mod_socache_shmcb.c>
SSLUseStapling On
SSLStaplingCache "shmcb:${APACHE_RUN_DIR}/ssl_stapling(32768)"
</IfModule>
</IfModule>
##
## Enable HSTS, even for subdomains.
##

View File

@ -6,7 +6,7 @@
##
## Requires the following Apache modules to be enabled:
## mod_rewrite
## mod_ssl or mod_gnutls
## mod_ssl
##
<Location /plinth>
RewriteEngine on

91
debian/changelog vendored
View File

@ -1,3 +1,94 @@
freedombox (21.9) unstable; urgency=medium
[ Fioddor Superconcentrado ]
* container: Don't fail if there's no fbx network
* container: freedombox-develop callable from anywhere
* lintian: Overrides for remove-on-upgrade dpkg conffiles flag
[ James Valleroy ]
* debian: Add gbp tag config
* container: Update stable image for bullseye
* backups: Add functional test to disable schedule backups
* avahi: Convert functional tests to non-BDD python format
* cockpit: Convert functional tests to non-BDD python format
* i2p: Convert functional tests to non-BDD python format
* infinoted: Convert functional tests to non-BDD python format
* minetest: Convert functional tests to non-BDD python format
* minidlna: Convert functional tests to non-BDD python format
* performance: Convert functional tests to non-BDD python format
* matrixsynapse: Convert functional tests to non-BDD python format
* jsxc: Convert functional tests to non-BDD python format
* backups: Convert functional tests to non-BDD python format
* locale: Update translation strings
* doc: Fetch latest manual
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ Michael Breidenbach ]
* Translated using Weblate (Swedish)
[ Andrij Mizyk ]
* Translated using Weblate (Ukrainian)
* Translated using Weblate (Ukrainian)
* Translated using Weblate (Ukrainian)
* Translated using Weblate (Ukrainian)
* Translated using Weblate (Ukrainian)
[ Tiago Zaniquelli ]
* plinth: remove diagnose command
[ Joseph Nuthalapati ]
* apache: Drop support for SSLv3, TLSv1 and TLSv1.1
* mediawiki: Backup and restore uploaded files
* mediawiki: Bump version number for 1.35 upgrade
* mediawiki: Enable a subset of default extensions
* mediawiki: Switch to MediaWiki 2020 logo
[ ikmaak ]
* Translated using Weblate (Dutch)
* Translated using Weblate (Dutch)
* Translated using Weblate (Dutch)
* Translated using Weblate (Dutch)
* Translated using Weblate (Dutch)
[ Sunil Mohan Adapa ]
* mediawiki: tests: functional: Fix races after flipping flags
* d/lintian-overrides: Drop override for a removed tag
* d/lintian-overrides: Override message for not supporting sysvinit
* d/lintian-overrides: Add override for manual outside .../doc/
* d/lintian-overrides: Drop workaround for remove-on-upgrade dpkg flag
* apache: Drop support for GnuTLS
* apache: Enable and prioritize HTTP/2 protocol
* apache: Setup Mozilla recommended configuration
* container: Fix the update command for new web server
* tests: Add some missing markers
* web_framework, tests: Workaround captcha 0.5.6 vs. Django 3.2
[ fliu ]
* email: Fix self.critical not callable error
* email: postconf.get_many_unsafe: batch query
* email: configure postfix domain names
[ Seyed mohammad ali Hosseinifard ]
* Translated using Weblate (Persian)
[ Veiko Aasa ]
* gitweb: tests: Fix test failures if initial default branch is not master
* gitweb: tests: Convert functional tests to non-BDD python format
* gitweb: tests: functional: Fix test failure if initial default branch is not master
[ Artem ]
* Translated using Weblate (Russian)
[ 109247019824 ]
* Translated using Weblate (Bulgarian)
[ 池边树下 ]
* Translated using Weblate (Chinese (Simplified))
-- James Valleroy <jvalleroy@mailbox.org> Sat, 18 Sep 2021 09:47:06 -0400
freedombox (21.8~bpo11+1) bullseye-backports; urgency=medium
* Rebuild for bullseye-backports.

8
debian/copyright vendored
View File

@ -65,7 +65,6 @@ Files: static/themes/default/icons/diaspora.png
static/themes/default/icons/ejabberd.png
static/themes/default/icons/ejabberd.svg
static/themes/default/icons/matrixsynapse.svg
static/themes/default/icons/mediawiki.svg
static/themes/default/icons/privoxy.png
static/themes/default/icons/privoxy.svg
static/themes/default/icons/radicale.svg
@ -82,7 +81,6 @@ Comment: Placed into public domain by authors (or)
Do not meet the threshold of originality
Tango Desktop Project
https://commons.wikimedia.org/wiki/File:Ejabberd_icon.png
https://commons.wikimedia.org/wiki/File:MediaWiki-notext.svg
https://radicale.org/css/logo.svg
https://github.com/resiprocate/resiprocate/blob/master/resip/stack/doc/reSIProcate-logo.svg
License: public-domain
@ -137,6 +135,12 @@ Copyright: 2017 Kishan Raval
Comment: https://github.com/thekishanraval/Logos
License: GPL-3+
Files: static/themes/default/icons/mediawiki.png
static/themes/default/icons/mediawiki.svg
Copyright: 2020 Serhio Magpie
Comment: https://commons.wikimedia.org/wiki/File:MediaWiki-2020-icon.svg
License: CC-BY-SA-4.0
Files: static/themes/default/icons/minetest.png
Copyright: 2011 erlehmann
License: CC-BY-SA-3.0

View File

@ -0,0 +1,5 @@
# Debian Policy Manual, Section 12.3: Any files that are used or read by
# programs but are also useful as stand alone documentation should be installed
# elsewhere, such as under /usr/share/package/, and then included via symbolic
# links in /usr/share/doc/package.
freedombox-doc-en: package-contains-documentation-outside-usr-share-doc usr/share/freedombox/manual/*

View File

@ -0,0 +1,5 @@
# Debian Policy Manual, Section 12.3: Any files that are used or read by
# programs but are also useful as stand alone documentation should be installed
# elsewhere, such as under /usr/share/package/, and then included via symbolic
# links in /usr/share/doc/package.
freedombox-doc-es: package-contains-documentation-outside-usr-share-doc usr/share/freedombox/manual/*

View File

@ -16,5 +16,11 @@ freedombox binary: non-standard-apache2-configuration-name *
# that requires significant effort.
freedombox binary: web-application-works-only-with-apache
# Temporary workaround for https://bugs.debian.org/992465
freedombox: systemd-service-file-outside-lib usr/lib/systemd/system/*.service
# FreedomBox adds systemd security features for other daemons in Debian. There
# is no equivalent for this in sysvinit. Sometimes, FreedomBox provide service
# files for packages that do not provide them. FreedomBox does not support
# sysvinit so no init.d equivalent is provided.
freedombox: package-supports-alternative-init-but-no-init.d-script usr/lib/systemd/system/*
# Not documentation
freedombox: package-contains-documentation-outside-usr-share-doc usr/share/plinth/static/jslicense.html

View File

@ -43,6 +43,9 @@ An alternative to downloading these images is to [[InstallingDebianOn/Allwinner|
=== Known Issues ===
* Revision G2 (written on the board): The current stable Debian11/bullseye image (from 2021-08-27) '''will not start an Ethernet connection!''' This means you can not continue with the installation process at first. This can be fixed by following [[https://wiki.debian.org/InstallingDebianOn/Allwinner#Olimex_A20-OLinuXino-LIME2__rev._F_and_newer_and_Debian11.2F_bullseye_kernel | this description]] after you [[https://wiki.debian.org/FreedomBox/Download#Installation | copied the image to your SD card]]. Or you Download and use the [[https://ftp.freedombox.org/pub/freedombox/pioneer/|Pioneer Edition image]] to fix the issue. It contains a slightly [[https://salsa.debian.org/freedombox-team/u-boot/commit/2cb18893ef|modified u-boot]].
* Revision G2 hardware has also [[DebianBug:927397|poor performance when transmitting Ethernet data in Gigabit mode]] for older FreedomBox releases. The procedure above or for rev. C fixes this.
* Revision C hardware has [[DebianBug:845128|poor performance when receiving Ethernet data in Gigabit mode]]. To workaround the problem, you can switch to 100 Mbps mode instead of Gigabit mode. Login to your !FreedomBox as root (or plugin the SD card into another computer) and create the file /etc/NetworkManager/dispatcher.d/20-fix-ethernet-problem with the following contents:
{{{
#!/bin/bash
@ -65,7 +68,7 @@ case ${ACTION} in
;;
esac
}}}
* Revision G2 hardware has [[DebianBug:927397|poor performance when transmitting Ethernet data in Gigabit mode]]. Download and use the [[https://ftp.freedombox.org/pub/freedombox/pioneer/|Pioneer Edition image]] to fix the issue. It contains a slightly [[https://salsa.debian.org/freedombox-team/u-boot/commit/2cb18893ef|modified u-boot]]. The above workaround to put the Ethernet into 100 Mbps mode also fixes this issue.
* Revision K hardware is [[https://salsa.debian.org/freedombox-team/freedom-maker/issues/148|not working properly]].
## END_INCLUDE

View File

@ -16,14 +16,19 @@
|| '''App/Feature''' || '''Support in Version''' || '''Notes''' ||
|| Avahi || - || no backup needed ||
|| Backups || - || no backup needed ||
|| bepasty || 20.14 || ||
|| Bind || 0.41 || ||
|| calibre || 20.15 || ||
|| Cockpit || - || no backup needed ||
|| Coturn || 20.8 || ||
|| Datetime || 0.41 || ||
|| Deluge || 0.41 || does not include downloaded/seeding files ||
|| Diagnostics || - || no backup needed ||
|| Dynamic DNS || 0.39 || ||
|| ejabberd || 0.39 || includes all data and configuration ||
|| Firewall || - || no backup needed ||
|| Gitweb || 19.19 || ||
|| I2P || 19.6 || ||
|| ikiwiki || 0.39 || includes all wikis/blogs and their content ||
|| infinoted || 0.39 || includes all data and keys ||
|| JSXC || - || no backup needed ||
@ -31,6 +36,7 @@
|| Matrix Synapse || 0.39 || includes media and uploads ||
|| !MediaWiki || 0.39 || includes wiki pages and uploaded files ||
|| Minetest || 0.39 || ||
|| MiniDLNA || 19.23 || ||
|| MLDonkey || 19.0 || ||
|| Monkeysphere || 0.42 || ||
|| Mumble || 0.40 || ||
@ -43,6 +49,7 @@
|| Quassel || 0.40 || includes users and logs ||
|| Radicale || 0.39 || includes calendar and cards data for all users ||
|| Roundcube || - || no backup needed ||
|| Samba || 19.22 || does not include the data in the shared folders ||
|| SearX || - || no backup needed ||
|| Secure Shell (SSH) Server || 0.41 || includes host keys ||
|| Security || 0.41 || ||
@ -57,6 +64,8 @@
|| Transmission || 0.40 || does not include downloaded/seeding files ||
|| Upgrades || 0.42 || ||
|| Users || No || No plans currently to implement backup ||
|| Wordpress || 21.8 || ||
|| Zoph || 21.3 || ||
=== How to install and use Backups ===

View File

@ -18,16 +18,16 @@ The easiest way to get support is by using the [[https://discuss.freedombox.org|
To post new content, you will need to register for an account with name and email address (but you can provide pseudonym and non-primary email address). By watching topics and categories or by enabling 'mailing list mode' in your account preferences, you can interact with the forum by just sending and receiving emails similar to a mailing list.
== IRC #freedombox ==
Providing you are familiar with [[http://www.irchelp.org/|Internet Relay Chat]] (IRC) and [[http://www.irchelp.org/irchelp/clients/|IRC client]], you can get an instant online help from the community on '''irc.debian.org''', channel '''#freedombox'''. Potentially it takes some time before some member is answering you, be patient, a reaction will come later.
== Matrix ==
You can join our Matrix room '''#freedombox:matrix.org'''. The room is federated with the IRC channel and remembers the chat history.
If you do not yet have a client installed, you can [[https://riot.im/app/#/room/#freedombox:matrix.org|use your web browser to join]].
For more options, see this [[https://matrix.to/#/#freedombox:matrix.org|matrix client overview page]].
== IRC #freedombox ==
Providing you are familiar with [[http://www.irchelp.org/|Internet Relay Chat]] (IRC) and [[http://www.irchelp.org/irchelp/clients/|IRC client]], you can get an instant online help from the community on '''irc.debian.org''', channel '''#freedombox'''. Potentially it takes some time before some member is answering you, be patient, a reaction will come later.
== Email ==
!FreedomBox users and contributors can be reached by email via a discussion list. In order to ask a question and get an answer from the community, please register from the [[https://lists.alioth.debian.org/mailman/listinfo/freedombox-discuss|mailing list page]] providing your email adress and creating a password. You can also read [[http://lists.alioth.debian.org/pipermail/freedombox-discuss/|discussions archives]]. This list gathers about 700 readers.

View File

@ -10,6 +10,26 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version.
== FreedomBox 21.9 (2021-09-18) ==
=== Highlights ===
* mediawiki: Backup and restore uploaded files
* mediawiki: Enable a subset of default extensions
=== Other Changes ===
* apache: Update security settings
* Drop support for GnuTLS
* Drop support for SSLv3, TLSv1 and TLSv1.1
* Enable and prioritize HTTP/2 protocol
* Setup Mozilla recommended configuration
* locale: Update translations for Bulgarian, Chinese (Simplified), Dutch, Persian, Russian, Swedish, Turkish, Ukrainian
* mediawiki: Handle upgrade for 1.35
* mediawiki: Switch to !MediaWiki 2020 logo
* plinth: remove diagnose command
* Add workaround for Django 3.2 with captcha 0.5.6
== FreedomBox 21.8 (2021-08-30) ==
=== Highlights ===

View File

@ -43,6 +43,9 @@ An alternative to downloading these images is to [[InstallingDebianOn/Allwinner|
=== Known Issues ===
* Revision G2 (written on the board): The current stable Debian11/bullseye image (from 2021-08-27) '''will not start an Ethernet connection!''' This means you can not continue with the installation process at first. This can be fixed by following [[https://wiki.debian.org/InstallingDebianOn/Allwinner#Olimex_A20-OLinuXino-LIME2__rev._F_and_newer_and_Debian11.2F_bullseye_kernel | this description]] after you [[https://wiki.debian.org/FreedomBox/Download#Installation | copied the image to your SD card]]. Or you Download and use the [[https://ftp.freedombox.org/pub/freedombox/pioneer/|Pioneer Edition image]] to fix the issue. It contains a slightly [[https://salsa.debian.org/freedombox-team/u-boot/commit/2cb18893ef|modified u-boot]].
* Revision G2 hardware has also [[DebianBug:927397|poor performance when transmitting Ethernet data in Gigabit mode]] for older FreedomBox releases. The procedure above or for rev. C fixes this.
* Revision C hardware has [[DebianBug:845128|poor performance when receiving Ethernet data in Gigabit mode]]. To workaround the problem, you can switch to 100 Mbps mode instead of Gigabit mode. Login to your !FreedomBox as root (or plugin the SD card into another computer) and create the file /etc/NetworkManager/dispatcher.d/20-fix-ethernet-problem with the following contents:
{{{
#!/bin/bash
@ -65,7 +68,7 @@ case ${ACTION} in
;;
esac
}}}
* Revision G2 hardware has [[DebianBug:927397|poor performance when transmitting Ethernet data in Gigabit mode]]. Download and use the [[https://ftp.freedombox.org/pub/freedombox/pioneer/|Pioneer Edition image]] to fix the issue. It contains a slightly [[https://salsa.debian.org/freedombox-team/u-boot/commit/2cb18893ef|modified u-boot]]. The above workaround to put the Ethernet into 100 Mbps mode also fixes this issue.
* Revision K hardware is [[https://salsa.debian.org/freedombox-team/freedom-maker/issues/148|not working properly]].
## END_INCLUDE

View File

@ -16,14 +16,19 @@
|| '''App/Funcionalidad''' || '''Soporte en Versión''' || '''Notas''' ||
|| Avahi || - || no precisa ''backup'' ||
|| Backups || - || no precisa ''backup'' ||
|| bepasty || 20.14 || ||
|| Bind || 0.41 || ||
|| calibre || 20.15 || ||
|| Cockpit || - || no precisa ''backup'' ||
|| Coturn || 20.8 || ||
|| Datetime || 0.41 || ||
|| Deluge || 0.41 || '''no''' incluye archivos descargados ni semillas ||
|| Diagnostics || - || no precisa ''backup'' ||
|| Dynamic DNS || 0.39 || ||
|| ejabberd || 0.39 || incluye todos los datos y configuración ||
|| Firewall || - || no precisa ''backup'' ||
|| Gitweb || 19.19 || ||
|| I2P || 19.6 || ||
|| ikiwiki || 0.39 || incluye todos los wikis/blogs y sus contenidos ||
|| infinoted || 0.39 || incluye todos los datos y claves ||
|| JSXC || - || no precisa ''backup'' ||
@ -31,6 +36,7 @@
|| Matrix Synapse || 0.39 || incluye media y cargas ||
|| !MediaWiki || 0.39 || incluye páginas de wiki y archivos adjuntos ||
|| Minetest || 0.39 || ||
|| MiniDLNA || 19.23 || ||
|| MLDonkey || 19.0 || ||
|| Monkeysphere || 0.42 || ||
|| Mumble || 0.40 || ||
@ -43,6 +49,7 @@
|| Quassel || 0.40 || incluye usuarios y registros de ejeución (''logs'') ||
|| Radicale || 0.39 || incluye calendario y datos de tarjetas de todos los usuarios ||
|| Roundcube || - || no precisa ''backup'' ||
|| Samba || 19.22 || ''no''' incluye datos de las carpetas compartidas ||
|| SearX || - || no precisa ''backup'' ||
|| Secure Shell (SSH) Server || 0.41 || incluye las claves del servidor ||
|| Security || 0.41 || ||
@ -57,6 +64,8 @@
|| Transmission || 0.40 || '''no''' incluye archivos descargados ni semillas ||
|| Upgrades || 0.42 || ||
|| Users || No || sin planes para implementar ''backup'', de momento ||
|| Wordpress || 21.8 || ||
|| Zoph || 21.3 || ||
=== Cómo instalar y usar Backups ===

View File

@ -15,16 +15,16 @@ La forma más fácil de obtener soporte es usando el [[https://discuss.freedombo
Para publicar contenido nuevo necesitarás registrarte con un nombre y una dirección de correo electrónico (pero puedes usar un pseudonimo y una dirección secundaria). Habilitando el 'modo lista de correo' ('mailing list mode') en las preferencias de tu cuenta, puedes interactuar con el foro simplemente enviando y recibiendo correos electrónicos como en una lista de correo.
== IRC #freedombox ==
Si te manejas con IRC ([[http://www.irchelp.org/|Internet Relay Chat]]) y [[http://www.irchelp.org/irchelp/clients/|sus clientes]] puedes obtener ayuda en línea instantánea de la comunidad en el canal '''#freedombox''' de '''irc.debian.org'''. Quizá pase un tiempo antes de que algún miembro te responda. Sé paciente. Ya llegará alguna respuesta.
== Matrix ==
Puedes unirte a la sala Matrix '''#freedombox:matrix.org'''. La sala está federada con el canal IRC y recuerda la historia del chat.
Si aún no tienes un cliente instalado puedes [[https://riot.im/app/#/room/#freedombox:matrix.org|usar tu navegador web para unirte]].
Para más opciones, visita la [[https://matrix.to/#/#freedombox:matrix.org|página de introducción al cliente matrix]].
== IRC #freedombox ==
Si te manejas con IRC ([[http://www.irchelp.org/|Internet Relay Chat]]) y [[http://www.irchelp.org/irchelp/clients/|sus clientes]] puedes obtener ayuda en línea instantánea de la comunidad en el canal '''#freedombox''' de '''irc.debian.org'''. Quizá pase un tiempo antes de que algún miembro te responda. Sé paciente. Ya llegará alguna respuesta.
== Correo Electrónico ==
Se puede acceder a los usuarios y contribuyentes de !FreedomBox mediante e-mail con la lista de correo. Para formular preguntas y recibir respuestas de la comunidad por favor regístrate en la [[https://lists.alioth.debian.org/mailman/listinfo/freedombox-discuss|página de la lista de correo]] dando tu dirección de correo electrónico y creando una contraseña. También puedes leer los [[http://lists.alioth.debian.org/pipermail/freedombox-discuss/|hilos archivados]]. Esta lista reune a cerca de 700 lectores.

View File

@ -10,6 +10,26 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version.
== FreedomBox 21.9 (2021-09-18) ==
=== Highlights ===
* mediawiki: Backup and restore uploaded files
* mediawiki: Enable a subset of default extensions
=== Other Changes ===
* apache: Update security settings
* Drop support for GnuTLS
* Drop support for SSLv3, TLSv1 and TLSv1.1
* Enable and prioritize HTTP/2 protocol
* Setup Mozilla recommended configuration
* locale: Update translations for Bulgarian, Chinese (Simplified), Dutch, Persian, Russian, Swedish, Turkish, Ukrainian
* mediawiki: Handle upgrade for 1.35
* mediawiki: Switch to !MediaWiki 2020 logo
* plinth: remove diagnose command
* Add workaround for Django 3.2 with captcha 0.5.6
== FreedomBox 21.8 (2021-08-30) ==
=== Highlights ===

View File

@ -3,4 +3,4 @@
Package init file.
"""
__version__ = '21.8'
__version__ = '21.9'

View File

@ -2,7 +2,6 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
import argparse
import importlib
import logging
import sys
@ -36,8 +35,6 @@ def parse_arguments():
parser.add_argument(
'--setup-no-install', default=False, nargs='*',
help='run setup tasks without installing packages and exit')
parser.add_argument('--diagnose', action='store_true', default=False,
help='run diagnostic tests and exit')
parser.add_argument('--list-dependencies', default=False, nargs='*',
help='list package dependencies for essential modules')
parser.add_argument('--list-modules', default=False, nargs='*',
@ -84,26 +81,6 @@ def list_modules(modules_type):
sys.exit()
def run_diagnostics_and_exit():
"""Run diagostics on all modules and exit."""
module = importlib.import_module('plinth.modules.diagnostics.diagnostics')
error_code = 0
try:
module.run_on_all_modules()
except Exception as exception:
logger.exception('Error running diagnostics - %s', exception)
error_code = 2
for module, results in module.current_results['results'].items():
for test, result_value in results:
print('{result_value}: {module}: {test}'.format(
result_value=result_value, test=test, module=module))
if result_value != 'passed':
error_code = 1
sys.exit(error_code)
def adapt_config(arguments):
"""Give commandline arguments precedence over config entries"""
for argument_name in precedence_commandline_arguments:
@ -160,9 +137,6 @@ def main():
if arguments.list_modules is not False:
list_modules(arguments.list_modules)
if arguments.diagnose:
run_diagnostics_and_exit()
setup.run_setup_in_background()
glib.run()

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2020-06-10 15:41+0000\n"
"Last-Translator: aiman an <an1f3@hotmail.com>\n"
"Language-Team: Arabic (Saudi Arabia) <https://hosted.weblate.org/projects/"
@ -1878,6 +1878,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7608,6 +7612,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-15 21:34+0000\n"
"Last-Translator: 109247019824 <stoyan@gmx.com>\n"
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/bg/>\n"
"Language: bg\n"
@ -17,11 +17,11 @@ 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.5-dev\n"
"X-Generator: Weblate 4.9-dev\n"
#: doc/dev/_templates/layout.html:11
msgid "Page source"
msgstr ""
msgstr "Изходен код на страницата"
#: plinth/context_processors.py:23 plinth/views.py:80
msgid "FreedomBox"
@ -30,17 +30,17 @@ msgstr "FreedomBox"
#: plinth/daemon.py:103
#, python-brace-format
msgid "Service {service_name} is running"
msgstr ""
msgstr "Услугата {service_name} работи"
#: plinth/daemon.py:130
#, python-brace-format
msgid "Listening on {kind} port {listen_address}:{port}"
msgstr ""
msgstr "Слушане на {kind} порт {listen_address}:{port}"
#: plinth/daemon.py:134
#, python-brace-format
msgid "Listening on {kind} port {port}"
msgstr ""
msgstr "Слушане на {kind} порт {port}"
#: plinth/daemon.py:202
#, python-brace-format
@ -53,32 +53,28 @@ msgid "Cannot connect to {host}:{port}"
msgstr "Не може да се свърже с {host}:{port}"
#: plinth/forms.py:39
#, fuzzy
msgid "Select a domain name to be used with this application"
msgstr "Изберете име на домейн, което да се ползва с това приложение"
msgstr "Изберете име на домейн, което да се използва с това приложение"
#: plinth/forms.py:41
#, fuzzy
msgid ""
"Warning! The application may not work properly if domain name is changed "
"later."
msgstr ""
"Внимание! Приложението може да не работи коректно, ако по-късно се промени "
"името на домейна."
"Предупреждение! Приложението може да не работи правилно, ако името на "
"домейна бъде променено по-късно."
#: plinth/forms.py:49
msgid "Language"
msgstr "Език"
#: plinth/forms.py:50
#, fuzzy
msgid "Language to use for presenting this web interface"
msgstr "Език, на който ще се показва този уеб интерфейс"
msgstr "Език, на който да се показва този интерфейс"
#: plinth/forms.py:57
#, fuzzy
msgid "Use the language preference set in the browser"
msgstr "Използване езиковите настройки на браузъра"
msgstr "Използване на предпочитания от четеца език"
#: plinth/middleware.py:59 plinth/templates/setup.html:18
msgid "Application installed."
@ -95,21 +91,19 @@ msgid "Error installing application: {error}"
msgstr "Грешка при инсталиране на приложението: {error}"
#: plinth/modules/apache/__init__.py:41
#, fuzzy
#| msgid "Web Server"
msgid "Apache HTTP Server"
msgstr "Уеб Сървър"
msgstr "Сървър на Apache HTTP"
#: plinth/modules/apache/__init__.py:44
#: plinth/modules/monkeysphere/templates/monkeysphere.html:49
#: plinth/modules/monkeysphere/templates/monkeysphere_details.html:46
msgid "Web Server"
msgstr "Уеб Сървър"
msgstr "Уеб сървър"
#: plinth/modules/apache/__init__.py:50
#, python-brace-format
msgid "{box_name} Web Interface (Plinth)"
msgstr "{box_name} Уеб Интерфейс (Plinth)"
msgstr "{box_name} Уеб интерфейс (Plinth)"
#: plinth/modules/apache/components.py:122
#, python-brace-format
@ -131,14 +125,20 @@ msgid ""
"disabled to improve security especially when connecting to a hostile local "
"network."
msgstr ""
"Откриването на услуги позволява на други устройства в мрежата да откриват "
"вашия {box_name} и услугите, които се предоставят от него. Също така "
"позволява на {box_name} да открива други устройства и услуги, работещи в "
"локалната мрежа. Откриването на услуги не е от съществено значение и работи "
"само във вътрешни мрежи. То може да бъде спряно, за да се подобри "
"сигурността, особено когато се свързвате към враждебна локална мрежа."
#: plinth/modules/avahi/__init__.py:59
msgid "Service Discovery"
msgstr ""
msgstr "Откриване на услуги"
#: plinth/modules/avahi/__init__.py:69
msgid "Local Network Domain"
msgstr ""
msgstr "Домейн на местната мрежа"
#: plinth/modules/backups/__init__.py:34
msgid "Backups allows creating and managing backup archives."
@ -147,13 +147,16 @@ msgstr ""
#: plinth/modules/backups/__init__.py:54 plinth/modules/backups/__init__.py:200
#: plinth/modules/backups/__init__.py:245
msgid "Backups"
msgstr ""
msgstr "Резервни копия"
#: plinth/modules/backups/__init__.py:197
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:203
msgid "Enable a Backup Schedule"
@ -164,7 +167,7 @@ msgstr ""
#: plinth/modules/storage/__init__.py:323
#, python-brace-format
msgid "Go to {app_name}"
msgstr ""
msgstr "Към {app_name}"
#: plinth/modules/backups/__init__.py:242
#, python-brace-format
@ -1885,6 +1888,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -5245,20 +5252,18 @@ msgid "Share enabled."
msgstr ""
#: plinth/modules/samba/views.py:106
#, fuzzy, python-brace-format
#| msgid "Error installing application: {error}"
#, python-brace-format
msgid "Error enabling share: {error_message}"
msgstr "Грешка при инсталиране на приложението: {error}"
msgstr "Грешка при разрешаване на споделянето: {error_message}"
#: plinth/modules/samba/views.py:111
msgid "Share disabled."
msgstr ""
#: plinth/modules/samba/views.py:116
#, fuzzy, python-brace-format
#| msgid "Error installing application: {error}"
#, python-brace-format
msgid "Error disabling share: {error_message}"
msgstr "Грешка при инсталиране на приложението: {error}"
msgstr "Грешка при забраняване на споделянето: {error_message}"
#: plinth/modules/searx/__init__.py:25
msgid ""
@ -6541,10 +6546,8 @@ msgid "There is a new %(box_name)s version available."
msgstr ""
#: plinth/modules/upgrades/templates/upgrades_configure.html:35
#, fuzzy
#| msgid "FreedomBox"
msgid "Your Freedombox needs an update!"
msgstr "FreedomBox"
msgstr "Вашият Freedombox се нуждае от обновяване!"
#: plinth/modules/upgrades/templates/upgrades_configure.html:47
msgid ""
@ -7625,6 +7628,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-06-16 07:33+0000\n"
"Last-Translator: Oymate <dhruboadittya96@gmail.com>\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/freedombox/"
@ -1876,6 +1876,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7622,6 +7626,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-25 11:32+0000\n"
"Last-Translator: Milan <mobrcian@hotmail.com>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/freedombox/"
@ -2126,6 +2126,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Chyba při nastavování doménového názvu: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8856,7 +8862,7 @@ msgstr "Instalace %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% dokončeno"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "gudžarátština"

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Danish <https://hosted.weblate.org/projects/freedombox/"
@ -2090,6 +2090,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Kunne ikke sætte domænenavn: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8762,7 +8768,7 @@ msgstr "Installerer %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% færdig"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-07-24 18:34+0000\n"
"Last-Translator: Johannes Keyser <joke@fsfe.org>\n"
"Language-Team: German <https://hosted.weblate.org/projects/freedombox/"
@ -2138,6 +2138,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Fehler beim Setzen des Domainnamens: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8870,7 +8876,7 @@ msgstr "%(package_names)s wird installiert: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s %% abgeschlossen"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1873,6 +1873,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7601,6 +7605,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-04-14 04:27+0000\n"
"Last-Translator: Michalis <michalisntovas@yahoo.gr>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/freedombox/"
@ -2155,6 +2155,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Σφάλμα κατά τη ρύθμιση ονόματος διδαδικτύου: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8976,7 +8982,7 @@ msgstr "Εγκατάσταση του %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "ολοκληρώθηκε το %(percentage)s%%"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-03-12 13:03+0000\n"
"Last-Translator: Fioddor Superconcentrado <fioddor@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/freedombox/"
@ -2120,6 +2120,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Error al establecer nombre de dominio: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8741,7 +8747,7 @@ msgstr "Instalando %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% completado"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-07 11:34+0000\n"
"Last-Translator: Seyed mohammad ali Hosseinifard <ali_hosseine@yahoo.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/fa/>\n"
"Language: fa\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.5-dev\n"
"X-Generator: Weblate 4.8.1-dev\n"
#: doc/dev/_templates/layout.html:11
msgid "Page source"
@ -31,7 +31,7 @@ msgstr "FreedomBox"
#: plinth/daemon.py:103
#, python-brace-format
msgid "Service {service_name} is running"
msgstr ""
msgstr "سرویس {service_name} در حال اجراست"
#: plinth/daemon.py:130
#, fuzzy, python-brace-format
@ -54,10 +54,8 @@ msgid "Cannot connect to {host}:{port}"
msgstr "نمی‌توان به {host}:{port} وصل شد"
#: plinth/forms.py:39
#, fuzzy
#| msgid "Invalid domain name"
msgid "Select a domain name to be used with this application"
msgstr "نام دامنه معتبر نیست"
msgstr "نام دامنه‌ای را برای استفاده با این برنامه انتخاب کنید"
#: plinth/forms.py:41
msgid ""
@ -108,7 +106,7 @@ msgstr "سرور وب"
#: plinth/modules/apache/__init__.py:50
#, python-brace-format
msgid "{box_name} Web Interface (Plinth)"
msgstr ""
msgstr "رابط وب {box_name} (Plinth)"
#: plinth/modules/apache/components.py:122
#, fuzzy, python-brace-format
@ -168,10 +166,9 @@ msgstr ""
#: plinth/modules/backups/__init__.py:207
#: plinth/modules/backups/__init__.py:254
#: plinth/modules/storage/__init__.py:323
#, fuzzy, python-brace-format
#| msgid "About {box_name}"
#, python-brace-format
msgid "Go to {app_name}"
msgstr "دربارهٔ {box_name}"
msgstr "رفتن به {app_name}"
#: plinth/modules/backups/__init__.py:242
#, python-brace-format
@ -182,12 +179,12 @@ msgstr ""
#: plinth/modules/backups/__init__.py:250
msgid "Error During Backup"
msgstr ""
msgstr "خظا هنگام پشتیبان‌گیری"
#: plinth/modules/backups/forms.py:33
#, python-brace-format
msgid "{app} (No data to backup)"
msgstr ""
msgstr "{app} (داده‌ای برای پشتیبان‌گیری نیست)"
#: plinth/modules/backups/forms.py:53
msgid "Enable scheduled backups"
@ -247,10 +244,8 @@ msgid "Apps to include in the backup"
msgstr ""
#: plinth/modules/backups/forms.py:98
#, fuzzy
#| msgid "Create Connection"
msgid "Repository"
msgstr "ساختن اتصال"
msgstr "مخزن"
#: plinth/modules/backups/forms.py:100
#: plinth/modules/backups/templates/backups_delete.html:17
@ -2094,6 +2089,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "خطا در هنگام تنظیم نام دامنه: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8140,14 +8141,12 @@ msgid "Launch web client"
msgstr ""
#: plinth/templates/clients-button.html:25
#, fuzzy
#| msgid "BitTorrent Web Client (Deluge)"
msgid "Client Apps"
msgstr "برنامهٔ تحت وب بیت‌تورنت (Deluge)"
msgstr "برنامه‌های کارخواه"
#: plinth/templates/clients.html:17
msgid "Web"
msgstr ""
msgstr "وب"
#: plinth/templates/clients.html:42
msgid "Desktop"
@ -8155,11 +8154,11 @@ msgstr ""
#: plinth/templates/clients.html:53
msgid "GNU/Linux"
msgstr ""
msgstr "گنو/لینوکس"
#: plinth/templates/clients.html:55
msgid "Windows"
msgstr ""
msgstr "ویندوز"
#: plinth/templates/clients.html:57
msgid "macOS"
@ -8184,11 +8183,11 @@ msgstr ""
#: plinth/templates/clients.html:104
msgid "Package"
msgstr ""
msgstr "بسته"
#: plinth/templates/clients.html:111
msgid "Debian:"
msgstr ""
msgstr "دبیان:"
#: plinth/templates/clients.html:114
msgid "Homebrew:"
@ -8234,11 +8233,11 @@ msgstr ""
#: plinth/templates/index.html:140
msgid "Source Code"
msgstr ""
msgstr "کد منبع"
#: plinth/templates/index.html:143 plinth/templates/toolbar.html:19
msgid "Donate"
msgstr ""
msgstr "کمک مالی"
#: plinth/templates/index.html:147
#, fuzzy
@ -8247,11 +8246,11 @@ msgstr "FreedomBox"
#: plinth/templates/index.html:154
msgid "IRC Chatroom"
msgstr ""
msgstr "گپ سرای آی‌آرسی"
#: plinth/templates/index.html:159
msgid "Mailing list"
msgstr ""
msgstr "فهرست پستی"
#: plinth/templates/internal-zone.html:11
#, python-format
@ -8259,6 +8258,8 @@ msgid ""
"<em>%(service_name)s</em> is available only on internal networks or when the "
"client is connected to %(box_name)s through VPN."
msgstr ""
"<em>%(service_name)s</em> تنها در شبکه‌های داخلی یا هنگامی که کارخواه از طریق "
"وی‌پی‌ان به %(box_name)s متصل شده است در دسترس می‌باشد."
#: plinth/templates/internal-zone.html:17
msgid "Currently there are no network interfaces configured as internal."
@ -8273,13 +8274,11 @@ msgstr ""
#: plinth/templates/messages.html:11
msgid "Close"
msgstr ""
msgstr "بستن"
#: plinth/templates/notifications-dropdown.html:11
#, fuzzy
#| msgid "No certficate"
msgid "Notifications"
msgstr "بدون گواهی دیجیتال"
msgstr "اعلان‌ها"
#: plinth/templates/port-forwarding-info.html:8
msgid "Port Forwarding"
@ -8310,7 +8309,7 @@ msgstr ""
#: plinth/templates/port-forwarding-info.html:37
msgid "Protocol"
msgstr ""
msgstr "پروتکل"
#: plinth/templates/port-forwarding-info.html:38
msgid "From Router/WAN Ports"
@ -8366,7 +8365,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Plinth 0.6\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2016-01-31 22:24+0530\n"
"Last-Translator: Sunil Mohan Adapa <sunil@medhas.org>\n"
"Language-Team: Plinth Developers <freedombox-discuss@lists.alioth.debian."
@ -2216,6 +2216,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "ERROR SETTING DOMAIN NAME: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8932,7 +8938,7 @@ msgstr "INSTALLING %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% COMPLETE"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-05-31 22:13+0000\n"
"Last-Translator: Coucouf <coucouf@coucouf.fr>\n"
"Language-Team: French <https://hosted.weblate.org/projects/freedombox/"
@ -2151,6 +2151,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Erreur lors de la définition du nom de domaine : {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8923,7 +8929,7 @@ msgstr "Installation de %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% effectué"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Galician <https://hosted.weblate.org/projects/freedombox/"
@ -1881,6 +1881,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7635,7 +7639,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Gujarati <https://hosted.weblate.org/projects/freedombox/"
@ -2051,6 +2051,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "ક્ષેત્રીય નામ સ્થાપિત કરતાં ભૂલ થઇ: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7962,7 +7968,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Hindi <https://hosted.weblate.org/projects/freedombox/"
@ -2140,6 +2140,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "{exception}: डोमेन नाम सेट करने में एरर"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8751,7 +8757,7 @@ msgstr "%(package_names)s:%(status)s इंस्टॉलेशन किया
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% पूर्ण"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-04-22 21:32+0000\n"
"Last-Translator: Benedek Nagy <benedek@bndk.club>\n"
"Language-Team: Hungarian <https://hosted.weblate.org/projects/freedombox/"
@ -2118,6 +2118,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Hiba a domain név beállítása közben: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8604,7 +8610,7 @@ msgstr "%(package_names)s telepítése: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "befejezettségi szint: %(percentage)s%%"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gudzsaráti"

View File

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Indonesian (FreedomBox)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-06-24 00:42+0000\n"
"Last-Translator: Reza Almanda <rezaalmanda27@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/freedombox/"
@ -2089,6 +2089,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Kesalahan pengaturan nama domain: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8102,7 +8108,7 @@ msgstr "Memasang %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s %% selesai"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Bahasa Gujarat"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-02-20 22:50+0000\n"
"Last-Translator: Dietmar <sagen@permondes.de>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/freedombox/"
@ -2086,6 +2086,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Errore impostazione nome di dominio: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8256,7 +8262,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% completata"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-05-20 12:32+0000\n"
"Last-Translator: Jacque Fresco <aidter@use.startmail.com>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/freedombox/"
@ -1875,6 +1875,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7603,6 +7607,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2020-07-16 16:41+0000\n"
"Last-Translator: Yogesh <yogesh@karnatakaeducation.org.in>\n"
"Language-Team: Kannada <https://hosted.weblate.org/projects/freedombox/"
@ -1875,6 +1875,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7605,6 +7609,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-02-22 10:50+0000\n"
"Last-Translator: Kornelijus Tvarijanavičius <kornelitvari@protonmail.com>\n"
"Language-Team: Lithuanian <https://hosted.weblate.org/projects/freedombox/"
@ -1876,6 +1876,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7604,6 +7608,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-08-19 13:51+0000\n"
"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/"
@ -2121,6 +2121,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Feil ved innstilling/setting av domenenavn: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8847,7 +8853,7 @@ msgstr "Installere %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% fullført"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-04-22 21:32+0000\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-18 13:33+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/freedombox/"
"freedombox/nl/>\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.7-dev\n"
"X-Generator: Weblate 4.9-dev\n"
"X-Language: nl_NL\n"
"X-Source-Language: C\n"
@ -2084,92 +2084,88 @@ msgstr ""
"de <a href=\"%(index_url)s\">Instellingen</a> pagina."
#: plinth/modules/email_server/__init__.py:49
#, fuzzy
#| msgid "Chat Server"
msgid "Email Server"
msgstr "Chatserver"
msgstr "E-mailserver"
#: plinth/modules/email_server/__init__.py:81
msgid "Powered by Postfix, Dovecot & Rspamd"
msgstr ""
msgstr "Maakt gebruik van Postfix, Dovecot &amp; Rspamd"
#: plinth/modules/email_server/aliases/__init__.py:66
#: plinth/modules/email_server/aliases/__init__.py:73
msgid "The alias was taken"
msgstr ""
msgstr "Deze alias is al in gebruik"
#: plinth/modules/email_server/aliases/models.py:13
msgid "Must be at least 2 characters long"
msgstr ""
msgstr "Moet ten minste 2 tekens lang zijn"
#: plinth/modules/email_server/aliases/models.py:15
msgid "Contains illegal characters"
msgstr ""
msgstr "Bevat ongeldige tekens"
#: plinth/modules/email_server/aliases/models.py:17
msgid "Must start and end with a-z or 0-9"
msgstr ""
msgstr "Moet beginnen en eindigen met a-z of 0-9"
#: plinth/modules/email_server/aliases/models.py:19
msgid "Cannot be a number"
msgstr ""
msgstr "Kan geen getal zijn"
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Domeinnaam instellen mislukt: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
#| msgid "Directory does not exist."
msgid "User does not exist"
msgstr "Map bestaat niet."
msgstr "Gebruiker bestaat niet"
#: plinth/modules/email_server/audit/ldap.py:66
msgid "Postfix-Dovecot SASL integration"
msgstr ""
msgstr "Postfix-Dovecot SASL-integratie"
#: plinth/modules/email_server/audit/ldap.py:67
msgid "Postfix alias maps"
msgstr ""
msgstr "Postfix aliasverwijzingen"
#: plinth/modules/email_server/audit/ldap.py:68
msgid "Postfix local recipient maps"
msgstr ""
msgstr "Lokale Postfix ontvanger verwijzingen"
#: plinth/modules/email_server/audit/rcube.py:31
#, fuzzy
#| msgid "unavailable"
msgid "RoundCube availability"
msgstr "niet beschikbaar"
msgstr "RoundCube-beschikbaarheid"
#: plinth/modules/email_server/audit/rcube.py:32
msgid "RoundCube configured for FreedomBox email"
msgstr ""
msgstr "RoundCube geconfigureerd voor FreedomBox-e-mail"
#: plinth/modules/email_server/audit/spam.py:86
msgid "Inbound and outbound mail filters"
msgstr ""
msgstr "Filters voor inkomende en uitgaande e-mail"
#: plinth/modules/email_server/audit/tls.py:80
msgid "Postfix TLS parameters"
msgstr ""
msgstr "Postfix TLS-parameters"
#: plinth/modules/email_server/audit/tls.py:81
msgid "Postfix uses a TLS certificate"
msgstr ""
msgstr "Postfix gebruikt een TLS-certificaat"
#: plinth/modules/email_server/audit/tls.py:90
#, fuzzy
#| msgid "No certificate"
msgid "Has a TLS certificate"
msgstr "Geen certificaat"
msgstr "Heeft een TLS-certificaat"
#: plinth/modules/email_server/forms.py:7
#, fuzzy
#| msgid "Domain"
msgid "domain"
msgstr "Domein"
msgstr "domein"
#: plinth/modules/email_server/forms.py:14
msgid "New alias (without @domain)"
msgstr ""
msgstr "Nieuwe alias (zonder @domein)"
#: plinth/modules/email_server/manifest.py:6
#: plinth/modules/roundcube/__init__.py:55
@ -2178,46 +2174,36 @@ msgid "Roundcube"
msgstr "Roundcube"
#: plinth/modules/email_server/manifest.py:12
#, fuzzy
#| msgid "Mozilla Thunderbird"
msgid "Thunderbird"
msgstr "Mozilla Thunderbird"
msgstr "Thunderbird"
#: plinth/modules/email_server/manifest.py:27
msgid "K-9 Mail"
msgstr ""
msgstr "K-9 Mail"
#: plinth/modules/email_server/manifest.py:40
msgid "FairEmail"
msgstr ""
msgstr "FairEmail"
#: plinth/modules/email_server/templates/email_alias.html:12
msgid "You have no email aliases."
msgstr ""
msgstr "Je hebt geen e-mailaliassen."
#: plinth/modules/email_server/templates/email_alias.html:21
#, fuzzy
#| msgid "Disabled"
msgid "Disable selected"
msgstr "Uitgeschakeld"
msgstr "Selectie uitschakelen"
#: plinth/modules/email_server/templates/email_alias.html:24
#, fuzzy
#| msgid "cable is connected"
msgid "Enable selected"
msgstr "kabel is verbonden"
msgstr "Selectie inschakelen"
#: plinth/modules/email_server/templates/email_alias.html:27
#, fuzzy
#| msgid "Deleted selected snapshots"
msgid "Delete selected"
msgstr "Verwijderde geselecteerde snapshots"
msgstr "Verwijder selectie"
#: plinth/modules/email_server/templates/email_alias.html:31
#, fuzzy
#| msgid "Create a new backup"
msgid "Create a new email alias"
msgstr "Maak een nieuwe back-up"
msgstr "Nieuwe e-mailalias maken"
#: plinth/modules/email_server/templates/email_alias.html:38
#: plinth/modules/tahoe/templates/tahoe-post-setup.html:59
@ -2225,10 +2211,8 @@ msgid "Add"
msgstr "Toevoegen"
#: plinth/modules/email_server/templates/email_domains.html:19
#, fuzzy
#| msgid "Backups"
msgid "New value"
msgstr "Back-ups"
msgstr "Nieuwe waarde"
#: plinth/modules/email_server/templates/email_domains.html:31
#: plinth/modules/email_server/templates/email_security.html:23
@ -2241,83 +2225,67 @@ msgstr "Update"
#: plinth/modules/email_server/templates/email_form_base.html:12
msgid "There was a problem with your request. Please try again."
msgstr ""
msgstr "Er was een probleem met dit verzoek. Probeer het opnieuw."
#: plinth/modules/email_server/templates/email_security.html:13
msgid "Postfix TLS"
msgstr ""
msgstr "Postfix TLS"
#: plinth/modules/email_server/templates/email_security.html:18
msgid "Dovecot TLS"
msgstr ""
msgstr "Dovecot TLS"
#: plinth/modules/email_server/templates/email_server.html:14
msgid "Visit Rspamd administration interface"
msgstr ""
msgstr "Ga naar de Rspamd administration interface"
#: plinth/modules/email_server/templates/email_server.html:18
#, fuzzy
#| msgid "Service Type"
msgid "Service Alert"
msgstr "Dienst Type"
msgstr "Servicewaarschuwing"
#: plinth/modules/email_server/templates/email_server.html:38
msgid "Repair"
msgstr ""
msgstr "Herstellen"
#: plinth/modules/email_server/templates/my_mail.html:15
#, fuzzy
#| msgid "Path is not a directory."
msgid "You do not have a home directory."
msgstr "Pad is geen map."
msgstr "Je hebt geen homedirectory."
#: plinth/modules/email_server/templates/my_mail.html:17
msgid "Create one to begin receiving emails."
msgstr ""
msgstr "Aanmaken om e-mails te kunnen ontvangen."
#: plinth/modules/email_server/templates/my_mail.html:22
#, fuzzy
#| msgid "Updated media directory"
msgid "Create home directory"
msgstr "Mediamap bijgewerkt"
msgstr "Home directory aanmaken"
#: plinth/modules/email_server/templates/tls_form.html:10
#, fuzzy
#| msgid "Current status:"
msgid "Keep current settings"
msgstr "Huidige status:"
msgstr "Huidige instellingen behouden"
#: plinth/modules/email_server/templates/tls_form.html:19
#, fuzzy
#| msgid "Let's Encrypt"
msgid "Use Let's Encrypt"
msgstr "Let's Encrypt"
msgstr "Gebruik Let's Encrypt"
#: plinth/modules/email_server/templates/tls_form.html:24
#, fuzzy
#| msgid "Domain name set"
msgid "Common name"
msgstr "Domeinnaam ingesteld"
msgstr "Algemene naam"
#: plinth/modules/email_server/templates/tls_form.html:38
msgid "Use custom values"
msgstr ""
msgstr "Aangepaste waarden gebruiken"
#: plinth/modules/email_server/templates/tls_form.html:43
#, fuzzy
#| msgid "Certificate Status"
msgid "Certificate path"
msgstr "Certificaatstatus"
msgstr "Pad van certificaat"
#: plinth/modules/email_server/templates/tls_form.html:53
#, fuzzy
#| msgid "Private key of this machine"
msgid "Private key path"
msgstr "Privésleutel van deze machine"
msgstr "Pad van privésleutel"
#: plinth/modules/email_server/templates/tls_form.html:67
msgid "Use system default"
msgstr ""
msgstr "Systeem standaard gebruiken"
#: plinth/modules/email_server/views.py:24
#: plinth/modules/email_server/views.py:32 plinth/templates/base.html:110
@ -2326,12 +2294,12 @@ msgstr "Startpagina"
#: plinth/modules/email_server/views.py:25
msgid "My Mail"
msgstr ""
msgstr "Mijn e-mail"
#: plinth/modules/email_server/views.py:26
#: plinth/modules/email_server/views.py:33
msgid "My Aliases"
msgstr ""
msgstr "Mijn aliassen"
#: plinth/modules/email_server/views.py:27
#: plinth/modules/networks/templates/connection_show.html:259
@ -2347,23 +2315,19 @@ msgstr "Domeinen"
#: plinth/modules/email_server/views.py:104
#, python-brace-format
msgid "Internal error in {0}"
msgstr ""
msgstr "Interne fout in {0}"
#: plinth/modules/email_server/views.py:107
msgid "Check syslog for more information"
msgstr ""
msgstr "Controleer syslog voor meer informatie"
#: plinth/modules/email_server/views.py:181
#, fuzzy
#| msgid "Enable damage"
msgid "Enabled aliases"
msgstr "Inschakelen Schade"
msgstr "Aktieve aliassen"
#: plinth/modules/email_server/views.py:182
#, fuzzy
#| msgid "Disabled"
msgid "Disabled aliases"
msgstr "Uitgeschakeld"
msgstr "Inactieve aliassen"
#: plinth/modules/firewall/__init__.py:33
#, python-brace-format
@ -6227,23 +6191,16 @@ msgstr ""
"de kerndiensten en gebruikersinterface voor een FreedomBox server levert."
#: plinth/modules/security/templates/security_report.html:19
#, fuzzy
#| msgid ""
#| "The following table lists the current reported number, and historical "
#| "count, of security vulnerabilities for each installed app. More "
#| "information on the vulnerabilities can be found on the <a href=\"https://"
#| "security-tracker.debian.org/tracker/\">Debian Security Bug Tracker</a>."
msgid ""
"The following table lists the current reported number of security "
"vulnerabilities for each installed app. More information on the "
"vulnerabilities can be found on the <a href=\"https://security-tracker."
"debian.org/tracker/\">Debian Security Bug Tracker</a>."
msgstr ""
"In de volgende tabel wordt het huidige gerapporteerde aantal en het "
"historische aantal beveiligingsproblemen voor elke geïnstalleerde toepassing "
"weergegeven. Meer informatie over de kwetsbaarheden is te vinden op de <a "
"href=\"https://security-tracker.debian.org/tracker/\">Debian Security Bug "
"Tracker</a>."
"In de volgende tabel wordt het huidige gerapporteerde aantal "
"beveiligingsproblemen voor elke geïnstalleerde toepassing weergegeven. Meer "
"informatie over de kwetsbaarheden is te vinden op de <a href=\"https://"
"security-tracker.debian.org/tracker/\">Debian Security Bug Tracker</a>."
#: plinth/modules/security/templates/security_report.html:28
msgid ""
@ -8286,6 +8243,11 @@ msgid ""
"Administration interface and produced web pages are suitable for mobile "
"devices."
msgstr ""
"WordPress is een veelgebruikte methode om websites te maken en beheren. De "
"inhoud kan worden beheerd met een grafische interface. De indeling en "
"functionaliteit kan worden aangepast, en het uiterlijk kan worden veranderd "
"met thema's. De website en het beheer ervan is bruikbaar met een mobiel "
"apparaat."
#: plinth/modules/wordpress/__init__.py:42
#, python-brace-format
@ -8312,22 +8274,16 @@ msgstr ""
#: plinth/modules/wordpress/__init__.py:69
#: plinth/modules/wordpress/manifest.py:6
#, fuzzy
#| msgid "Address"
msgid "WordPress"
msgstr "Adres"
msgstr "WordPress"
#: plinth/modules/wordpress/__init__.py:70
#, fuzzy
#| msgid "Wiki and Blog"
msgid "Website and Blog"
msgstr "Wiki en Blog"
msgstr "Website en Blog"
#: plinth/modules/wordpress/forms.py:14
#, fuzzy
#| msgid "public access"
msgid "Public access"
msgstr "openbare toegang"
msgstr "Openbare toegang"
#: plinth/modules/wordpress/forms.py:15
msgid ""
@ -8784,7 +8740,7 @@ msgstr "Installeren van %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% voltooid"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-03-03 16:50+0000\n"
"Last-Translator: Karol Werner <karol@ppkt.eu>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/freedombox/"
@ -2075,6 +2075,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Błąd ustawiania nazwy domeny {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8175,7 +8181,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-05-08 22:33+0000\n"
"Last-Translator: ssantos <ssantos@web.de>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/freedombox/"
@ -1974,6 +1974,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Erro ao definir o nome do domínio: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7958,7 +7964,7 @@ msgstr "A instalar %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% concluída"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-02-01 18:42+0000\n"
"Last-Translator: Алексей Докучаев <deathlike333@gmail.com>\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-10 07:34+0000\n"
"Last-Translator: Artem <Localizer_in_Russian@protonmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/ru/>\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.5-dev\n"
"X-Generator: Weblate 4.8.1-dev\n"
#: doc/dev/_templates/layout.html:11
msgid "Page source"
@ -2104,6 +2104,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Ошибка параметра имени домена: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -2253,7 +2259,7 @@ msgstr "Тип службы"
#: plinth/modules/email_server/templates/email_server.html:38
msgid "Repair"
msgstr ""
msgstr "Исправление"
#: plinth/modules/email_server/templates/my_mail.html:15
#, fuzzy
@ -8766,7 +8772,7 @@ msgstr "Установка %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s%% завершено"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Гуджарати"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-04-27 13:32+0000\n"
"Last-Translator: HelaBasa <R45XvezA@protonmail.ch>\n"
"Language-Team: Sinhala <https://hosted.weblate.org/projects/freedombox/"
@ -1875,6 +1875,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7603,6 +7607,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/freedombox/"
@ -2025,6 +2025,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7871,7 +7875,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-06-07 12:34+0000\n"
"Last-Translator: Besnik Bleta <besnik@programeshqip.org>\n"
"Language-Team: Albanian <https://hosted.weblate.org/projects/freedombox/"
@ -2110,6 +2110,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Gabim në caktimin e emrin të përkatësisë: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8548,7 +8554,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujaratase"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Serbian <https://hosted.weblate.org/projects/freedombox/"
@ -1949,6 +1949,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7703,7 +7707,7 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-04-22 21:32+0000\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-01 16:33+0000\n"
"Last-Translator: Michael Breidenbach <leahc@tutanota.com>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/freedombox/"
"freedombox/sv/>\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.7-dev\n"
"X-Generator: Weblate 4.8.1-dev\n"
#: doc/dev/_templates/layout.html:11
msgid "Page source"
@ -2072,92 +2072,88 @@ msgstr ""
"din domän på systemet <a href=\"%(index_url)s\">Konfigurera</a> sidan."
#: plinth/modules/email_server/__init__.py:49
#, fuzzy
#| msgid "Chat Server"
msgid "Email Server"
msgstr "Chat-Server"
msgstr "E-postserver"
#: plinth/modules/email_server/__init__.py:81
msgid "Powered by Postfix, Dovecot & Rspamd"
msgstr ""
msgstr "Drivs av Postfix, Dovecot och Rspamd"
#: plinth/modules/email_server/aliases/__init__.py:66
#: plinth/modules/email_server/aliases/__init__.py:73
msgid "The alias was taken"
msgstr ""
msgstr "Aliasnamnet togs"
#: plinth/modules/email_server/aliases/models.py:13
msgid "Must be at least 2 characters long"
msgstr ""
msgstr "Måste vara minst 2 tecken lång"
#: plinth/modules/email_server/aliases/models.py:15
msgid "Contains illegal characters"
msgstr ""
msgstr "Innehåller otillåtna tecken"
#: plinth/modules/email_server/aliases/models.py:17
msgid "Must start and end with a-z or 0-9"
msgstr ""
msgstr "Måste börja och sluta med a-z eller 0-9"
#: plinth/modules/email_server/aliases/models.py:19
msgid "Cannot be a number"
msgstr ""
msgstr "Kan inte vara ett nummer"
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Fel inställning av domännamn: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
#| msgid "Directory does not exist."
msgid "User does not exist"
msgstr "Katalogen finns inte."
msgstr "Användaren finns inte"
#: plinth/modules/email_server/audit/ldap.py:66
msgid "Postfix-Dovecot SASL integration"
msgstr ""
msgstr "Integrering av Postfix-Dovecot SASL"
#: plinth/modules/email_server/audit/ldap.py:67
msgid "Postfix alias maps"
msgstr ""
msgstr "Postfix alias kartor"
#: plinth/modules/email_server/audit/ldap.py:68
msgid "Postfix local recipient maps"
msgstr ""
msgstr "Postfix lokala mottagarkartor"
#: plinth/modules/email_server/audit/rcube.py:31
#, fuzzy
#| msgid "unavailable"
msgid "RoundCube availability"
msgstr "otillgängligt"
msgstr "RoundCube tillgänglighet"
#: plinth/modules/email_server/audit/rcube.py:32
msgid "RoundCube configured for FreedomBox email"
msgstr ""
msgstr "RoundCube konfigurerad för FreedomBox e-post"
#: plinth/modules/email_server/audit/spam.py:86
msgid "Inbound and outbound mail filters"
msgstr ""
msgstr "Filter för inkommande och utgående e-post"
#: plinth/modules/email_server/audit/tls.py:80
msgid "Postfix TLS parameters"
msgstr ""
msgstr "Postfix TLS-parametrar"
#: plinth/modules/email_server/audit/tls.py:81
msgid "Postfix uses a TLS certificate"
msgstr ""
msgstr "Postfix använder ett TLS -certifikat"
#: plinth/modules/email_server/audit/tls.py:90
#, fuzzy
#| msgid "No certificate"
msgid "Has a TLS certificate"
msgstr "Inget certifikat"
msgstr "Har ett TLS-certifikat"
#: plinth/modules/email_server/forms.py:7
#, fuzzy
#| msgid "Domain"
msgid "domain"
msgstr "Domän"
msgstr "domain"
#: plinth/modules/email_server/forms.py:14
msgid "New alias (without @domain)"
msgstr ""
msgstr "Nytt alias (utan @domän)"
#: plinth/modules/email_server/manifest.py:6
#: plinth/modules/roundcube/__init__.py:55
@ -2166,46 +2162,36 @@ msgid "Roundcube"
msgstr "Roundcube"
#: plinth/modules/email_server/manifest.py:12
#, fuzzy
#| msgid "Mozilla Thunderbird"
msgid "Thunderbird"
msgstr "Mozilla Thunderbird"
msgstr "Thunderbird"
#: plinth/modules/email_server/manifest.py:27
msgid "K-9 Mail"
msgstr ""
msgstr "K-9 Mail"
#: plinth/modules/email_server/manifest.py:40
msgid "FairEmail"
msgstr ""
msgstr "FairEmail"
#: plinth/modules/email_server/templates/email_alias.html:12
msgid "You have no email aliases."
msgstr ""
msgstr "Du har inga e-postalias."
#: plinth/modules/email_server/templates/email_alias.html:21
#, fuzzy
#| msgid "Disabled"
msgid "Disable selected"
msgstr "Inaktiverad"
msgstr "Inaktivera markerad"
#: plinth/modules/email_server/templates/email_alias.html:24
#, fuzzy
#| msgid "cable is connected"
msgid "Enable selected"
msgstr "kabeln är ansluten"
msgstr "Aktivera markerad"
#: plinth/modules/email_server/templates/email_alias.html:27
#, fuzzy
#| msgid "Deleted selected snapshots"
msgid "Delete selected"
msgstr "Borttagna markerade ögonblicksbilder"
msgstr "Tabort valda"
#: plinth/modules/email_server/templates/email_alias.html:31
#, fuzzy
#| msgid "Create a new backup"
msgid "Create a new email alias"
msgstr "Skapa en ny säkerhetskopia"
msgstr "Skapa ett nytt e -postalias"
#: plinth/modules/email_server/templates/email_alias.html:38
#: plinth/modules/tahoe/templates/tahoe-post-setup.html:59
@ -2214,7 +2200,7 @@ msgstr "Lägg till"
#: plinth/modules/email_server/templates/email_domains.html:19
msgid "New value"
msgstr ""
msgstr "Nytt värde"
#: plinth/modules/email_server/templates/email_domains.html:31
#: plinth/modules/email_server/templates/email_security.html:23
@ -2227,83 +2213,67 @@ msgstr "Uppdatera"
#: plinth/modules/email_server/templates/email_form_base.html:12
msgid "There was a problem with your request. Please try again."
msgstr ""
msgstr "Ett problem uppstod med din begäran. Var god försök igen."
#: plinth/modules/email_server/templates/email_security.html:13
msgid "Postfix TLS"
msgstr ""
msgstr "Postfix TLS"
#: plinth/modules/email_server/templates/email_security.html:18
msgid "Dovecot TLS"
msgstr ""
msgstr "Dovecot TLS"
#: plinth/modules/email_server/templates/email_server.html:14
msgid "Visit Rspamd administration interface"
msgstr ""
msgstr "Besök Rspamd administrationsgränssnitt"
#: plinth/modules/email_server/templates/email_server.html:18
#, fuzzy
#| msgid "Service Type"
msgid "Service Alert"
msgstr "Servicetype"
msgstr "Servicevarning"
#: plinth/modules/email_server/templates/email_server.html:38
msgid "Repair"
msgstr ""
msgstr "Reparera"
#: plinth/modules/email_server/templates/my_mail.html:15
#, fuzzy
#| msgid "Path is not a directory."
msgid "You do not have a home directory."
msgstr "Sökvägen är inte en katalog."
msgstr "Du har ingen arbetskatalog."
#: plinth/modules/email_server/templates/my_mail.html:17
msgid "Create one to begin receiving emails."
msgstr ""
msgstr "Skapa en för att börja ta emot e-post."
#: plinth/modules/email_server/templates/my_mail.html:22
#, fuzzy
#| msgid "Updated media directory"
msgid "Create home directory"
msgstr "Uppdaterad mediekatalog"
msgstr "Skapa arbetskatalog"
#: plinth/modules/email_server/templates/tls_form.html:10
#, fuzzy
#| msgid "Current status:"
msgid "Keep current settings"
msgstr "Nuvarande status:"
msgstr "Behåll nuvarande inställningar"
#: plinth/modules/email_server/templates/tls_form.html:19
#, fuzzy
#| msgid "Let's Encrypt"
msgid "Use Let's Encrypt"
msgstr "Låt oss kryptera"
msgstr "Använd Let's Encrypt"
#: plinth/modules/email_server/templates/tls_form.html:24
#, fuzzy
#| msgid "Domain name set"
msgid "Common name"
msgstr "Domännamn inställt"
msgstr "Vanligt namn"
#: plinth/modules/email_server/templates/tls_form.html:38
msgid "Use custom values"
msgstr ""
msgstr "Använd anpassade värden"
#: plinth/modules/email_server/templates/tls_form.html:43
#, fuzzy
#| msgid "Certificate Status"
msgid "Certificate path"
msgstr "Certifikatets status"
msgstr "Sökväg för certifikat"
#: plinth/modules/email_server/templates/tls_form.html:53
#, fuzzy
#| msgid "Private key of this machine"
msgid "Private key path"
msgstr "Maskinens privata nyckel"
msgstr "Sökväg för den privata nyckeln"
#: plinth/modules/email_server/templates/tls_form.html:67
msgid "Use system default"
msgstr ""
msgstr "Använd systemstandard"
#: plinth/modules/email_server/views.py:24
#: plinth/modules/email_server/views.py:32 plinth/templates/base.html:110
@ -2312,12 +2282,12 @@ msgstr "Hem"
#: plinth/modules/email_server/views.py:25
msgid "My Mail"
msgstr ""
msgstr "Min e-post"
#: plinth/modules/email_server/views.py:26
#: plinth/modules/email_server/views.py:33
msgid "My Aliases"
msgstr ""
msgstr "Mina alias"
#: plinth/modules/email_server/views.py:27
#: plinth/modules/networks/templates/connection_show.html:259
@ -2333,23 +2303,19 @@ msgstr "Domäner"
#: plinth/modules/email_server/views.py:104
#, python-brace-format
msgid "Internal error in {0}"
msgstr ""
msgstr "Internt fel i {0}"
#: plinth/modules/email_server/views.py:107
msgid "Check syslog for more information"
msgstr ""
msgstr "Kontrollera syslog för mer information"
#: plinth/modules/email_server/views.py:181
#, fuzzy
#| msgid "Enable damage"
msgid "Enabled aliases"
msgstr "Aktivera skador"
msgstr "Aktiverade alias"
#: plinth/modules/email_server/views.py:182
#, fuzzy
#| msgid "Disabled"
msgid "Disabled aliases"
msgstr "Inaktiverad"
msgstr "Inaktiverade alias"
#: plinth/modules/firewall/__init__.py:33
#, python-brace-format
@ -6173,22 +6139,16 @@ msgstr ""
"server."
#: plinth/modules/security/templates/security_report.html:19
#, fuzzy
#| msgid ""
#| "The following table lists the current reported number, and historical "
#| "count, of security vulnerabilities for each installed app. More "
#| "information on the vulnerabilities can be found on the <a href=\"https://"
#| "security-tracker.debian.org/tracker/\">Debian Security Bug Tracker</a>."
msgid ""
"The following table lists the current reported number of security "
"vulnerabilities for each installed app. More information on the "
"vulnerabilities can be found on the <a href=\"https://security-tracker."
"debian.org/tracker/\">Debian Security Bug Tracker</a>."
msgstr ""
"I följande tabell visas det aktuella rapporterade antalet och det historiska "
"antalet säkerhetsbrister för varje installerad app. Mer information om "
"sårbarheterna finns på <a href=\"https://security-tracker.debian.org/tracker/"
"\">Debian Security Bug Tracker</a>."
"I följande tabell visas det aktuella antalet rapporterade säkerhetsbrister "
"för varje installerad app. Mer information om sårbarheterna finns på <a href="
"\"https://security-tracker.debian.org/tracker/\">Debian Security Bug "
"Tracker</a>."
#: plinth/modules/security/templates/security_report.html:28
msgid ""
@ -8216,6 +8176,11 @@ msgid ""
"Administration interface and produced web pages are suitable for mobile "
"devices."
msgstr ""
"WordPress är ett populärt sätt att skapa och hantera webbplatser och "
"bloggar. Innehållet kan hanteras med hjälp av ett visuellt gränssnitt. "
"Webbplatsernas layout och funktionalitet kan anpassas. Utseende kan väljas "
"med hjälp av teman. Administrationsgränssnittet och producerade webbsidor är "
"lämpliga för mobila enheter."
#: plinth/modules/wordpress/__init__.py:42
#, python-brace-format
@ -8225,6 +8190,11 @@ msgid ""
"the correct domain name. Enable permalinks in administrator interface for "
"better URLs to your pages and posts."
msgstr ""
"Du måste köra WordPress-installationen genom att besöka appen innan du gör "
"webbplatsen tillgänglig för allmänheten nedan. Installationen måste köras "
"när du går in på {box_name} med rätt domännamn. Aktivera permalänkar i "
"administratörsgränssnittet för bättre webbadresser till dina sidor och "
"inlägg."
#: plinth/modules/wordpress/__init__.py:47
msgid ""
@ -8232,6 +8202,10 @@ msgid ""
"during setup. Bookmark the <a href=\"/wordpress/wp-admin/\">admin page</a> "
"to reach administration interface in the future."
msgstr ""
"WordPress har sina egna användarkonton. Det första administratörskontot "
"skapas under installationen. Lägg <a href=\"/wordpress/wp-admin/\">admin-"
"sidan</a> som ett bokmärke för att nå administrationsgränssnittet i "
"framtiden."
#: plinth/modules/wordpress/__init__.py:51
msgid ""
@ -8239,23 +8213,20 @@ msgid ""
"from administrator interface. Additional plugins or themes may be installed "
"and upgraded at your own risk."
msgstr ""
"Efter en uppgradering av en större version måste du manuellt köra "
"databasuppgradering från administratörsgränssnittet. Ytterligare plugins "
"eller teman kan installeras och uppgraderas på egen risk."
#: plinth/modules/wordpress/__init__.py:69
#: plinth/modules/wordpress/manifest.py:6
#, fuzzy
#| msgid "Address"
msgid "WordPress"
msgstr "Adress"
msgstr "WordPress"
#: plinth/modules/wordpress/__init__.py:70
#, fuzzy
#| msgid "Wiki and Blog"
msgid "Website and Blog"
msgstr "Wiki och Blogg"
msgstr "Webbplats och blogg"
#: plinth/modules/wordpress/forms.py:14
#, fuzzy
#| msgid "public access"
msgid "Public access"
msgstr "Publik tillgång"
@ -8264,6 +8235,9 @@ msgid ""
"Allow all visitors. Disabling allows only administrators to view the "
"WordPress site or blog. Enable only after performing initial WordPress setup."
msgstr ""
"Tillåt alla besökare. Om du inaktiverar detta kan endast administratörer se "
"WordPress-webbplatsen eller bloggen. Aktivera endast efter den första "
"installationen av WordPress."
#: plinth/modules/zoph/__init__.py:33
#, python-brace-format
@ -8713,7 +8687,7 @@ msgstr "Installerar %(package_names)s:%(status)s"
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s %% färdigt"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1874,6 +1874,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7602,6 +7606,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-05-17 18:31+0000\n"
"Last-Translator: chilumula vamshi krishna <kannakrishna1625@gmail.com>\n"
"Language-Team: Telugu <https://hosted.weblate.org/projects/freedombox/"
@ -2087,6 +2087,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "అధికారక్షేత్రం పేరు అమర్పులోపం: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
@ -8632,7 +8638,7 @@ msgstr "%(package_names)s నిక్షిప్తం అవుతోంద
msgid "%(percentage)s%% complete"
msgstr "%(percentage)s %% పూర్తి"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "గుజరాతీ"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-04-22 21:32+0000\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-01 16:33+0000\n"
"Last-Translator: Burak Yavuz <hitowerdigit@hotmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/freedombox/"
"freedombox/tr/>\n"
@ -16,7 +16,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.7-dev\n"
"X-Generator: Weblate 4.8.1-dev\n"
#: doc/dev/_templates/layout.html:11
msgid "Page source"
@ -2074,92 +2074,88 @@ msgstr ""
"ayarlayabilirsiniz."
#: plinth/modules/email_server/__init__.py:49
#, fuzzy
#| msgid "Chat Server"
msgid "Email Server"
msgstr "Sohbet Sunucusu"
msgstr "E-posta Sunucusu"
#: plinth/modules/email_server/__init__.py:81
msgid "Powered by Postfix, Dovecot & Rspamd"
msgstr ""
msgstr "Postfix, Dovecot ve Rspamd tarafından desteklenmektedir"
#: plinth/modules/email_server/aliases/__init__.py:66
#: plinth/modules/email_server/aliases/__init__.py:73
msgid "The alias was taken"
msgstr ""
msgstr "Kod adı alındı"
#: plinth/modules/email_server/aliases/models.py:13
msgid "Must be at least 2 characters long"
msgstr ""
msgstr "En az 2 karakter uzunluğunda olmak zorundadır"
#: plinth/modules/email_server/aliases/models.py:15
msgid "Contains illegal characters"
msgstr ""
msgstr "Geçersiz karakterler içeriyor"
#: plinth/modules/email_server/aliases/models.py:17
msgid "Must start and end with a-z or 0-9"
msgstr ""
msgstr "A-z veya 0-9 ile başlamalı ve bitmelidir"
#: plinth/modules/email_server/aliases/models.py:19
msgid "Cannot be a number"
msgstr ""
msgstr "Sayı olamaz"
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Etki alanı adı ayarlanırken hata oldu: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
#, fuzzy
#| msgid "Directory does not exist."
msgid "User does not exist"
msgstr "Dizin mevcut değil."
msgstr "Kullanıcı mevcut değil"
#: plinth/modules/email_server/audit/ldap.py:66
msgid "Postfix-Dovecot SASL integration"
msgstr ""
msgstr "Postfix-Dovecot SASL bütünleştirmesi"
#: plinth/modules/email_server/audit/ldap.py:67
msgid "Postfix alias maps"
msgstr ""
msgstr "Postfix kod adı eşlemeleri"
#: plinth/modules/email_server/audit/ldap.py:68
msgid "Postfix local recipient maps"
msgstr ""
msgstr "Postfix yerel alıcı eşlemeleri"
#: plinth/modules/email_server/audit/rcube.py:31
#, fuzzy
#| msgid "unavailable"
msgid "RoundCube availability"
msgstr "kullanılamaz"
msgstr "RoundCube kullanılabilirliği"
#: plinth/modules/email_server/audit/rcube.py:32
msgid "RoundCube configured for FreedomBox email"
msgstr ""
msgstr "RoundCube, FreedomBox e-postası için yapılandırıldı"
#: plinth/modules/email_server/audit/spam.py:86
msgid "Inbound and outbound mail filters"
msgstr ""
msgstr "Gelen ve giden posta süzgeçleri"
#: plinth/modules/email_server/audit/tls.py:80
msgid "Postfix TLS parameters"
msgstr ""
msgstr "Postfix TLS parametreleri"
#: plinth/modules/email_server/audit/tls.py:81
msgid "Postfix uses a TLS certificate"
msgstr ""
msgstr "Postfix bir TLS sertifikası kullanır"
#: plinth/modules/email_server/audit/tls.py:90
#, fuzzy
#| msgid "No certificate"
msgid "Has a TLS certificate"
msgstr "Sertifika yok"
msgstr "TLS sertifikası var"
#: plinth/modules/email_server/forms.py:7
#, fuzzy
#| msgid "Domain"
msgid "domain"
msgstr "Etki Alanı"
msgstr "etki alanı"
#: plinth/modules/email_server/forms.py:14
msgid "New alias (without @domain)"
msgstr ""
msgstr "Yeni kod adı (@domain olmadan)"
#: plinth/modules/email_server/manifest.py:6
#: plinth/modules/roundcube/__init__.py:55
@ -2168,46 +2164,36 @@ msgid "Roundcube"
msgstr "Roundcube"
#: plinth/modules/email_server/manifest.py:12
#, fuzzy
#| msgid "Mozilla Thunderbird"
msgid "Thunderbird"
msgstr "Mozilla Thunderbird"
msgstr "Thunderbird"
#: plinth/modules/email_server/manifest.py:27
msgid "K-9 Mail"
msgstr ""
msgstr "K-9 Mail"
#: plinth/modules/email_server/manifest.py:40
msgid "FairEmail"
msgstr ""
msgstr "FairEmail"
#: plinth/modules/email_server/templates/email_alias.html:12
msgid "You have no email aliases."
msgstr ""
msgstr "E-posta kod adlarınız yok."
#: plinth/modules/email_server/templates/email_alias.html:21
#, fuzzy
#| msgid "Disabled"
msgid "Disable selected"
msgstr "Etkisizleştirildi"
msgstr "Seçileni etkisizleştir"
#: plinth/modules/email_server/templates/email_alias.html:24
#, fuzzy
#| msgid "cable is connected"
msgid "Enable selected"
msgstr "kablo bağlı"
msgstr "Seçileni etkinleştir"
#: plinth/modules/email_server/templates/email_alias.html:27
#, fuzzy
#| msgid "Deleted selected snapshots"
msgid "Delete selected"
msgstr "Seçilen anlık görüntüler silindi"
msgstr "Seçileni sil"
#: plinth/modules/email_server/templates/email_alias.html:31
#, fuzzy
#| msgid "Create a new backup"
msgid "Create a new email alias"
msgstr "Yeni bir yedek oluşturun"
msgstr "Yeni bir e-posta kod adı oluşturun"
#: plinth/modules/email_server/templates/email_alias.html:38
#: plinth/modules/tahoe/templates/tahoe-post-setup.html:59
@ -2216,7 +2202,7 @@ msgstr "Ekle"
#: plinth/modules/email_server/templates/email_domains.html:19
msgid "New value"
msgstr ""
msgstr "Yeni değer"
#: plinth/modules/email_server/templates/email_domains.html:31
#: plinth/modules/email_server/templates/email_security.html:23
@ -2229,83 +2215,67 @@ msgstr "Güncelle"
#: plinth/modules/email_server/templates/email_form_base.html:12
msgid "There was a problem with your request. Please try again."
msgstr ""
msgstr "İsteğiniz ile ilgili bir sorun oldu. Lütfen tekrar deneyin."
#: plinth/modules/email_server/templates/email_security.html:13
msgid "Postfix TLS"
msgstr ""
msgstr "Postfix TLS"
#: plinth/modules/email_server/templates/email_security.html:18
msgid "Dovecot TLS"
msgstr ""
msgstr "Dovecot TLS"
#: plinth/modules/email_server/templates/email_server.html:14
msgid "Visit Rspamd administration interface"
msgstr ""
msgstr "Rspamd yönetim arayüzünü ziyaret edin"
#: plinth/modules/email_server/templates/email_server.html:18
#, fuzzy
#| msgid "Service Type"
msgid "Service Alert"
msgstr "Hizmet Türü"
msgstr "Hizmet Uyarısı"
#: plinth/modules/email_server/templates/email_server.html:38
msgid "Repair"
msgstr ""
msgstr "Onar"
#: plinth/modules/email_server/templates/my_mail.html:15
#, fuzzy
#| msgid "Path is not a directory."
msgid "You do not have a home directory."
msgstr "Yol bir dizin değil."
msgstr "Giriş dizininiz yok."
#: plinth/modules/email_server/templates/my_mail.html:17
msgid "Create one to begin receiving emails."
msgstr ""
msgstr "E-posta almaya başlamak için bir tane oluşturun."
#: plinth/modules/email_server/templates/my_mail.html:22
#, fuzzy
#| msgid "Updated media directory"
msgid "Create home directory"
msgstr "Güncellenmiş ortam dizini"
msgstr "Giriş dizini oluştur"
#: plinth/modules/email_server/templates/tls_form.html:10
#, fuzzy
#| msgid "Current status:"
msgid "Keep current settings"
msgstr "Güncel durum:"
msgstr "Şu anki ayarları koru"
#: plinth/modules/email_server/templates/tls_form.html:19
#, fuzzy
#| msgid "Let's Encrypt"
msgid "Use Let's Encrypt"
msgstr "Let's Encrypt"
msgstr "Let's Encrypt'ı kullan"
#: plinth/modules/email_server/templates/tls_form.html:24
#, fuzzy
#| msgid "Domain name set"
msgid "Common name"
msgstr "Etki alanı adı ayarlandı"
msgstr "Ortak ad"
#: plinth/modules/email_server/templates/tls_form.html:38
msgid "Use custom values"
msgstr ""
msgstr "Özel değerler kullan"
#: plinth/modules/email_server/templates/tls_form.html:43
#, fuzzy
#| msgid "Certificate Status"
msgid "Certificate path"
msgstr "Sertifika Durumu"
msgstr "Sertifika yolu"
#: plinth/modules/email_server/templates/tls_form.html:53
#, fuzzy
#| msgid "Private key of this machine"
msgid "Private key path"
msgstr "Bu makinenin özel anahtarı"
msgstr "Özel anahtar yolu"
#: plinth/modules/email_server/templates/tls_form.html:67
msgid "Use system default"
msgstr ""
msgstr "Sistem varsayılanını kullan"
#: plinth/modules/email_server/views.py:24
#: plinth/modules/email_server/views.py:32 plinth/templates/base.html:110
@ -2314,12 +2284,12 @@ msgstr "Giriş"
#: plinth/modules/email_server/views.py:25
msgid "My Mail"
msgstr ""
msgstr "Postam"
#: plinth/modules/email_server/views.py:26
#: plinth/modules/email_server/views.py:33
msgid "My Aliases"
msgstr ""
msgstr "Kod Adlarım"
#: plinth/modules/email_server/views.py:27
#: plinth/modules/networks/templates/connection_show.html:259
@ -2335,23 +2305,19 @@ msgstr "Etki Alanları"
#: plinth/modules/email_server/views.py:104
#, python-brace-format
msgid "Internal error in {0}"
msgstr ""
msgstr "{0} içinde dahili hata"
#: plinth/modules/email_server/views.py:107
msgid "Check syslog for more information"
msgstr ""
msgstr "Daha fazla bilgi için syslog'u gözden geçirin"
#: plinth/modules/email_server/views.py:181
#, fuzzy
#| msgid "Enable damage"
msgid "Enabled aliases"
msgstr "Hasarı etkinleştir"
msgstr "Etkinleştirilmiş kod adları"
#: plinth/modules/email_server/views.py:182
#, fuzzy
#| msgid "Disabled"
msgid "Disabled aliases"
msgstr "Etkisizleştirildi"
msgstr "Etkisizleştirilmiş kod adları"
#: plinth/modules/firewall/__init__.py:33
#, python-brace-format
@ -6189,12 +6155,6 @@ msgstr ""
"sağlayan FreedomBox uygulamasında bildirilen %(count)s güvenlik açığı var."
#: plinth/modules/security/templates/security_report.html:19
#, fuzzy
#| msgid ""
#| "The following table lists the current reported number, and historical "
#| "count, of security vulnerabilities for each installed app. More "
#| "information on the vulnerabilities can be found on the <a href=\"https://"
#| "security-tracker.debian.org/tracker/\">Debian Security Bug Tracker</a>."
msgid ""
"The following table lists the current reported number of security "
"vulnerabilities for each installed app. More information on the "
@ -6202,9 +6162,9 @@ msgid ""
"debian.org/tracker/\">Debian Security Bug Tracker</a>."
msgstr ""
"Aşağıdaki tablo, yüklü her uygulama için bildirilen güvenlik açıklarının şu "
"anki sayısını ve geçmiş sayısını listeler. Güvenlik açıkları hakkında daha "
"fazla bilgi <a href=\"https://security-tracker.debian.org/tracker/\">Debian "
"Security Hata Tracker</a> sitesinde bulunabilir."
"anki sayısını listeler. Güvenlik açıkları hakkında daha fazla bilgi <a href="
"\"https://security-tracker.debian.org/tracker/\">Debian Security Hata "
"Tracker</a> sitesinde bulunabilir."
#: plinth/modules/security/templates/security_report.html:28
msgid ""
@ -8241,6 +8201,11 @@ msgid ""
"Administration interface and produced web pages are suitable for mobile "
"devices."
msgstr ""
"WordPress, web siteleri ve bloglar oluşturmanın ve yönetmenin yaygın bir "
"yoludur. İçerik, görsel bir arayüz kullanılarak yönetilebilir. Web "
"sayfalarının düzeni ve işlevselliği özelleştirilebilir. Görünüm temalar "
"kullanılarak seçilebilir. Yönetim arayüzü ve üretilen web sayfaları mobil "
"cihazlara uygundur."
#: plinth/modules/wordpress/__init__.py:42
#, python-brace-format
@ -8250,6 +8215,11 @@ msgid ""
"the correct domain name. Enable permalinks in administrator interface for "
"better URLs to your pages and posts."
msgstr ""
"Siteyi aşağıda herkese açık hale getirmeden önce uygulamayı ziyaret ederek "
"WordPress kurulumunu çalıştırmanız gerekir. Doğru etki alanı adıyla "
"{box_name} cihazına erişirken kurulum çalıştırılmak zorundadır. "
"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:47
msgid ""
@ -8257,6 +8227,9 @@ msgid ""
"during setup. Bookmark the <a href=\"/wordpress/wp-admin/\">admin page</a> "
"to reach administration interface in the future."
msgstr ""
"WordPress'in kendi kullanıcı hesapları vardır. İlk yönetici hesabı kurulum "
"sırasında oluşturulur. Gelecekte yönetim arayüzüne erişmek için <a href=\"/"
"wordpress/wp-admin/\">yönetici sayfası</a> yerini işaretleyin."
#: plinth/modules/wordpress/__init__.py:51
msgid ""
@ -8264,31 +8237,31 @@ msgid ""
"from administrator interface. Additional plugins or themes may be installed "
"and upgraded at your own risk."
msgstr ""
"Büyük bir sürüm yükseltmesinden sonra, yönetici arayüzünden veritabanı "
"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:69
#: plinth/modules/wordpress/manifest.py:6
#, fuzzy
#| msgid "Address"
msgid "WordPress"
msgstr "Adres"
msgstr "WordPress"
#: plinth/modules/wordpress/__init__.py:70
#, fuzzy
#| msgid "Wiki and Blog"
msgid "Website and Blog"
msgstr "Viki ve Blog"
msgstr "Web Sitesi ve Blog"
#: plinth/modules/wordpress/forms.py:14
#, fuzzy
#| msgid "public access"
msgid "Public access"
msgstr "herkese açık erişim"
msgstr "Herkese açık erişim"
#: plinth/modules/wordpress/forms.py:15
msgid ""
"Allow all visitors. Disabling allows only administrators to view the "
"WordPress site or blog. Enable only after performing initial WordPress setup."
msgstr ""
"Tüm ziyaretçilere izin verin. Etkisizleştirmek, sadece yöneticilerin "
"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:33
#, python-brace-format
@ -8737,7 +8710,7 @@ msgstr "Yüklenen %(package_names)s: %(status)s"
msgid "%(percentage)s%% complete"
msgstr "%%%(percentage)s tamamlandı"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "Gujarati"

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-07-28 08:34+0000\n"
"Last-Translator: bruh <quangtrung02hn16@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/freedombox/"
@ -2068,6 +2068,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "Lỗi khi đặt tên miền: {exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7815,6 +7821,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Plinth\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"PO-Revision-Date: 2021-06-12 02:32+0000\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-09-18 13:33+0000\n"
"Last-Translator: 池边树下 <mzky@163.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"freedombox/freedombox/zh_Hans/>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.7-dev\n"
"X-Generator: Weblate 4.9-dev\n"
#: doc/dev/_templates/layout.html:11
msgid "Page source"
@ -544,15 +544,7 @@ msgid "Restore data from"
msgstr "从 恢复数据"
#: plinth/modules/backups/templates/backups_upload.html:17
#, fuzzy, python-format
#| msgid ""
#| "\n"
#| " Upload a backup file downloaded from another %(box_name)s to "
#| "restore is\n"
#| " contents. You can choose the apps you wish to restore after "
#| "uploading a\n"
#| " backup file.\n"
#| " "
#, python-format
msgid ""
"\n"
" Upload a backup file downloaded from another %(box_name)s to restore "
@ -563,8 +555,8 @@ msgid ""
" "
msgstr ""
"\n"
" 上传一个从其它 %(box_name)s 下载的备份文件来恢复内容。\n"
" 备份上传完成后,你可以选择你想要恢复的应用。\n"
" 上传从另一个%(box_name)s下载的备份文件以恢复其内容。\n"
"\t您可以选择您希望在上传备份文件后恢复的应用程序。\n"
" "
#: plinth/modules/backups/templates/backups_upload.html:27
@ -716,7 +708,6 @@ msgid "Mounting failed"
msgstr "安装失败"
#: plinth/modules/bepasty/__init__.py:24
#, fuzzy
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, "
@ -728,7 +719,6 @@ msgstr ""
"一段时间后过期。"
#: plinth/modules/bepasty/__init__.py:28
#, fuzzy
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 "
@ -739,7 +729,6 @@ msgstr ""
"一旦你创建了一个密码,你就可以与应该拥有相关权限的用户分享它。"
#: plinth/modules/bepasty/__init__.py:32
#, fuzzy
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 "
@ -1316,15 +1305,15 @@ msgstr ""
#: plinth/modules/coturn/__init__.py:62
msgid "Coturn"
msgstr ""
msgstr "Coturn"
#: plinth/modules/coturn/__init__.py:63
msgid "VoIP Helper"
msgstr ""
msgstr "网络电话助手"
#: plinth/modules/coturn/forms.py:22
msgid "Invalid list of STUN/TURN Server URIs"
msgstr ""
msgstr "无效的STUN/TURN服务器URI列表"
#: plinth/modules/coturn/forms.py:30 plinth/modules/mumble/forms.py:21
#: plinth/modules/quassel/forms.py:22
@ -1338,11 +1327,11 @@ msgstr "子域"
msgid ""
"Select a domain to use TLS with. If the list is empty, please configure at "
"least one domain with certificates."
msgstr ""
msgstr "选择一个要使用TLS的域。如果列表中是空的请至少配置一个带有证书的域。"
#: plinth/modules/coturn/templates/coturn.html:15
msgid "Use the following URLs to configure your communication server:"
msgstr ""
msgstr "使用以下URL来配置你的通信服务器。"
#: plinth/modules/coturn/templates/coturn.html:24
#, fuzzy
@ -1362,7 +1351,7 @@ msgstr "日期与时间"
#: plinth/modules/datetime/__init__.py:116
msgid "Time synchronized to NTP server"
msgstr ""
msgstr "时间同步到NTP服务器"
#: plinth/modules/datetime/forms.py:18
msgid "Time Zone"
@ -1408,7 +1397,7 @@ msgstr ""
#: plinth/modules/deluge/__init__.py:47
#: plinth/modules/transmission/__init__.py:50
msgid "Download files using BitTorrent applications"
msgstr ""
msgstr "使用BitTorrent应用程序下载文件"
#: plinth/modules/deluge/__init__.py:51 plinth/modules/deluge/manifest.py:6
msgid "Deluge"
@ -1427,7 +1416,7 @@ msgstr "下载目录"
#: plinth/modules/deluge/manifest.py:7
msgid "Bittorrent client written in Python/PyGTK"
msgstr ""
msgstr "用Python/PyGTK编写的Bittorrent客户端"
#: plinth/modules/diagnostics/__init__.py:28
msgid ""
@ -1444,7 +1433,7 @@ msgstr "诊断程序"
#: plinth/modules/diagnostics/__init__.py:98
#: plinth/modules/email_server/templates/email_server.html:29
msgid "passed"
msgstr ""
msgstr "通过了"
#: plinth/modules/diagnostics/__init__.py:99
#: plinth/modules/email_server/templates/email_server.html:27
@ -1457,31 +1446,31 @@ msgstr "安装失败。"
#: plinth/modules/diagnostics/__init__.py:100
#: plinth/modules/email_server/templates/email_server.html:25
msgid "error"
msgstr ""
msgstr "错误"
#: plinth/modules/diagnostics/__init__.py:101
msgid "warning"
msgstr ""
msgstr "警告"
#. Translators: This is the unit of computer storage Mebibyte similar to
#. Megabyte.
#: plinth/modules/diagnostics/__init__.py:204
msgid "MiB"
msgstr ""
msgstr "MiB"
#. Translators: This is the unit of computer storage Gibibyte similar to
#. Gigabyte.
#: plinth/modules/diagnostics/__init__.py:209
msgid "GiB"
msgstr ""
msgstr "GiB"
#: plinth/modules/diagnostics/__init__.py:216
msgid "You should disable some apps to reduce memory usage."
msgstr ""
msgstr "你应该禁用一些应用程序以减少内存的使用。"
#: plinth/modules/diagnostics/__init__.py:221
msgid "You should not install any new apps on this system."
msgstr ""
msgstr "你不应该在这个系统上安装任何新的应用程序。"
#: plinth/modules/diagnostics/__init__.py:233
#, no-python-format, python-brace-format
@ -1489,10 +1478,12 @@ msgid ""
"System is low on memory: {percent_used}% used, {memory_available} "
"{memory_available_unit} free. {advice_message}"
msgstr ""
"系统内存不足。{percent_used}%已用,{memory_available} {memory_available_unit}"
"可用。{advice_message}。"
#: plinth/modules/diagnostics/__init__.py:235
msgid "Low Memory"
msgstr ""
msgstr "低内存"
#: plinth/modules/diagnostics/templates/diagnostics.html:17
#: plinth/modules/diagnostics/templates/diagnostics_button.html:11
@ -1514,6 +1505,9 @@ msgid ""
" App: %(app_name)s\n"
" "
msgstr ""
"\n"
" 应用程序。%(app_name)s\n"
" "
#: plinth/modules/diagnostics/templates/diagnostics_app.html:10
msgid "Diagnostic Results"
@ -1522,7 +1516,7 @@ msgstr "诊断结果"
#: plinth/modules/diagnostics/templates/diagnostics_app.html:12
#, python-format
msgid "App: %(app_name)s"
msgstr ""
msgstr "应用程序。%(app_name)s"
#: plinth/modules/diagnostics/templates/diagnostics_app.html:21
#, fuzzy
@ -1546,16 +1540,16 @@ msgstr "诊断测试"
msgid ""
"diaspora* is a decentralized social network where you can store and control "
"your own data."
msgstr ""
msgstr "diaspora*是一个去中心化的社交网络,你可以存储和控制自己的数据。"
#: plinth/modules/diaspora/__init__.py:68
#: plinth/modules/diaspora/manifest.py:23
msgid "diaspora*"
msgstr ""
msgstr "diaspora*"
#: plinth/modules/diaspora/__init__.py:69
msgid "Federated Social Network"
msgstr ""
msgstr "联合社交网络"
#: plinth/modules/diaspora/forms.py:13
msgid "Enable new user registrations"
@ -1563,13 +1557,14 @@ msgstr "实现新用户注册"
#: plinth/modules/diaspora/manifest.py:11
msgid "dandelion*"
msgstr ""
msgstr "dandelion*"
#: plinth/modules/diaspora/manifest.py:13
msgid ""
"It is an unofficial webview based client for the community-run, distributed "
"social network diaspora*"
msgstr ""
"它是一个非官方的基于webview的客户端用于社区运营的分布式社交网络diaspora*。"
#: plinth/modules/diaspora/templates/diaspora-post-setup.html:16
#, python-format
@ -1580,6 +1575,11 @@ msgid ""
"podname wouldn't be accessible. <br/> You can access the diaspora* pod at <a "
"href=\"https://diaspora.%(domain_name)s\"> diaspora.%(domain_name)s </a>"
msgstr ""
"diaspora*的pod域名被设置为<b>%(domain_name)s</b>。用户ID将看起来像"
"<i>username@diaspora.%(domain_name)s<i><br> 如果FreedomBox域名被改变所有用"
"以前podname注册的用户的数据将无法访问。<br> 你可以在<a href=\"https://"
"diaspora. %(domain_name)s\"> diaspora.%(domain_name)s </a>访问diaspora*荚。</"
"i></i>"
#: plinth/modules/diaspora/templates/diaspora-pre-setup.html:36
#: plinth/modules/matrixsynapse/templates/matrix-synapse-pre-setup.html:15
@ -1709,7 +1709,7 @@ msgstr "账户创建时使用的用户名"
#: plinth/modules/dynamicdns/forms.py:65
msgid "GnuDIP"
msgstr ""
msgstr "GnuDIP"
#: plinth/modules/dynamicdns/forms.py:68
#, fuzzy
@ -1760,7 +1760,7 @@ msgstr "查寻公开 IP 的 URL"
#: plinth/modules/dynamicdns/forms.py:119
msgid "Use IPv6 instead of IPv4"
msgstr ""
msgstr "使用IPv6而不是IPv4"
#: plinth/modules/dynamicdns/forms.py:142
msgid "Please provide an update URL or a GnuDIP server address"
@ -1895,10 +1895,12 @@ msgid ""
"ejabberd needs a STUN/TURN server for audio/video calls. Install the <a "
"href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
"ejabberd需要一个STUN/TURN服务器用于音频/视频呼叫。安装<a href="
"\"{coturn_url}\">Coturn</a>应用程序或配置一个外部服务器。"
#: plinth/modules/ejabberd/__init__.py:70
msgid "ejabberd"
msgstr ""
msgstr "ejabberd"
#: plinth/modules/ejabberd/__init__.py:71
#: plinth/modules/matrixsynapse/__init__.py:77
@ -1909,7 +1911,7 @@ msgstr "Web 服务器"
#: plinth/modules/ejabberd/forms.py:18
msgid "Enable Message Archive Management"
msgstr ""
msgstr "启用消息存档管理"
#: plinth/modules/ejabberd/forms.py:20
#, python-brace-format
@ -1919,10 +1921,13 @@ msgid ""
"history of a multi-user chat room. It depends on the client settings whether "
"the histories are stored as plain text or encrypted."
msgstr ""
"如果启用,您的{box_name}将存储聊天信息历史。这允许在多个客户端之间同步对话,"
"并读取多用户聊天室的历史。聊天记录是以纯文本还是加密形式存储,这取决于客户端"
"的设置。"
#: plinth/modules/ejabberd/forms.py:27 plinth/modules/matrixsynapse/forms.py:22
msgid "Automatically manage audio/video call setup"
msgstr ""
msgstr "自动管理音频/视频通话设置"
#: plinth/modules/ejabberd/forms.py:29
#, python-brace-format
@ -1931,14 +1936,16 @@ msgid ""
"server for ejabberd. Disable this if you want to use a different STUN/TURN "
"server."
msgstr ""
"将本地<a href=\"{coturn_url}\">coturn</a>应用程序配置为ejabberd的STUN/TURN服"
"务器。如果你想使用一个不同的STUN/TURN服务器请禁用此功能。"
#: plinth/modules/ejabberd/forms.py:36 plinth/modules/matrixsynapse/forms.py:31
msgid "STUN/TURN Server URIs"
msgstr ""
msgstr "STUN/TURN服务器URI"
#: plinth/modules/ejabberd/forms.py:38 plinth/modules/matrixsynapse/forms.py:33
msgid "List of public URIs of the STUN/TURN server, one on each line."
msgstr ""
msgstr "STUN/TURN服务器的公共URI列表每行一个。"
#: plinth/modules/ejabberd/forms.py:42 plinth/modules/matrixsynapse/forms.py:37
#, fuzzy
@ -2034,6 +2041,12 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
#, fuzzy
#| msgid "Error setting domain name: {exception}"
msgid "Postfix domain name config"
msgstr "设置域名错误:{exception}"
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -8700,7 +8713,7 @@ msgstr "正在安装 %(package_names)s%(status)s"
msgid "%(percentage)s%% complete"
msgstr "已完成 %(percentage)s%%"
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr "古吉拉特语"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-30 19:29-0400\n"
"POT-Creation-Date: 2021-09-18 09:34-0400\n"
"PO-Revision-Date: 2021-04-27 13:32+0000\n"
"Last-Translator: James Pan <bojaypan@mail.ru>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
@ -1894,6 +1894,10 @@ msgstr ""
msgid "Cannot be a number"
msgstr ""
#: plinth/modules/email_server/audit/domain.py:35
msgid "Postfix domain name config"
msgstr ""
#: plinth/modules/email_server/audit/home.py:23
#: plinth/modules/email_server/audit/home.py:32
msgid "User does not exist"
@ -7630,6 +7634,6 @@ msgstr ""
msgid "%(percentage)s%% complete"
msgstr ""
#: plinth/web_framework.py:113
#: plinth/web_framework.py:117
msgid "Gujarati"
msgstr ""

View File

@ -14,7 +14,7 @@ from plinth.modules.firewall.components import Firewall
from plinth.modules.letsencrypt.components import LetsEncrypt
from plinth.utils import format_lazy, is_valid_user_name
version = 8
version = 9
is_essential = True

View File

@ -1,18 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@system @essential @avahi
Feature: Avahi Service Discovery
Configure service discovery.
Background:
Given I'm a logged in user
Scenario: Disable avahi application
Given the avahi application is enabled
When I disable the avahi application
Then the avahi service should not be running
Scenario: Enable avahi application
Given the avahi application is disabled
When I enable the avahi application
Then the avahi service should be running

View File

@ -3,6 +3,27 @@
Functional, browser based tests for avahi app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('avahi.feature')
pytestmark = [pytest.mark.system, pytest.mark.essential, pytest.mark.avahi]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'avahi')
yield
functional.app_disable(session_browser, 'avahi')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'avahi')
functional.app_enable(session_browser, 'avahi')
assert functional.service_is_running(session_browser, 'avahi')
functional.app_disable(session_browser, 'avahi')
assert functional.service_is_not_running(session_browser, 'avahi')

View File

@ -1,31 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@backups @system
Feature: Backups module
Create and restore backups.
Background:
Given I'm a logged in user
Given the bind application is installed
Scenario: Browser waits for redirect after restoring a backup
Given the bind application is enabled
When I create a backup of the bind app data with name test_backups
And I restore the bind app data backup with name test_backups
And I open the main page
And I wait for 5 seconds
Then the main page should be shown
Scenario: Download, upload and restore a backup
Given the bind application is enabled
When I set bind forwarders to 1.1.1.1
And I create a backup of the bind app data with name test_backups
And I set bind forwarders to 1.0.0.1
And I download the app data backup with name test_backups
And I restore the downloaded app data backup
Then bind forwarders should be 1.1.1.1
Scenario: Set a schedule for a repository
Given the backup schedule is set to disable for 1 daily, 2 weekly and 3 monthly at 2:00 without app names
When I set the backup schedule to enable for 10 daily, 20 weekly and 30 monthly at 15:00 without app firewall
Then the schedule should be set to enable for 10 daily, 20 weekly and 30 monthly at 15:00 without app firewall

View File

@ -5,42 +5,77 @@ Functional, browser based tests for backups app.
import os
import tempfile
import time
import urllib.parse
import pytest
import requests
from pytest import fixture
from pytest_bdd import given, parsers, scenarios, then, when
from plinth.tests import functional
scenarios('backups.feature')
pytestmark = [pytest.mark.system, pytest.mark.backups]
@fixture(scope='session')
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'bind')
functional.app_enable(session_browser, 'bind')
yield
functional.app_disable(session_browser, 'bind')
_backup_schedule_disable(session_browser)
@pytest.fixture(scope='session')
def downloaded_file_info():
return dict()
@when(parsers.parse('I open the main page'))
def open_main_page(session_browser):
def test_browser_waits_after_restore(session_browser):
"""Test that browser waits for redirect after restoring a backup."""
functional.backup_create(session_browser, 'bind', 'test_backups')
functional.backup_restore(session_browser, 'bind', 'test_backups')
_open_main_page(session_browser)
time.sleep(5)
_assert_main_page_is_shown(session_browser)
@then(parsers.parse('the main page should be shown'))
def main_page_is_shown(session_browser):
def test_download_upload_restore(session_browser, downloaded_file_info):
"""Test download, upload, and restore a backup."""
functional.set_forwarders(session_browser, '1.1.1.1')
functional.backup_create(session_browser, 'bind', 'test_backups')
functional.set_forwarders(session_browser, '1.0.0.1')
_backup_download(session_browser, downloaded_file_info, 'test_backups')
_backup_restore_from_upload(session_browser, 'bind', downloaded_file_info)
assert functional.get_forwarders(session_browser) == '1.1.1.1'
def test_set_schedule(session_browser):
"""Test set a schedule for a repository."""
_backup_schedule_set(session_browser, enable=False, daily=1, weekly=2,
monthly=3, run_at=2, without_app='names')
_backup_schedule_set(session_browser, enable=True, daily=10, weekly=20,
monthly=30, run_at=15, without_app='firewall')
_backup_schedule_assert(session_browser, enable=True, daily=10, weekly=20,
monthly=30, run_at=15, without_app='firewall')
def _assert_main_page_is_shown(session_browser):
assert (session_browser.url.endswith('/plinth/'))
@when(
parsers.parse('I download the app data backup with name {archive_name:w}'))
def backup_download(session_browser, downloaded_file_info, archive_name):
def _backup_download(session_browser, downloaded_file_info, archive_name):
file_path = _download(session_browser, archive_name)
downloaded_file_info['path'] = file_path
@when(parsers.parse('I restore the downloaded app data backup'))
def backup_restore_from_upload(session_browser, app_name,
downloaded_file_info):
def _backup_restore_from_upload(session_browser, app_name,
downloaded_file_info):
path = downloaded_file_info["path"]
try:
_upload_and_restore(session_browser, app_name, path)
@ -50,34 +85,10 @@ def backup_restore_from_upload(session_browser, app_name,
os.remove(path)
@given(
parsers.parse('the backup schedule is set to {enable:w} for {daily:d} '
'daily, {weekly:d} weekly and {monthly:d} monthly at '
'{run_at:d}:00 without app {without_app:w}'))
def backup_schedule_set(session_browser, enable, daily, weekly, monthly,
run_at, without_app):
_backup_schedule_set(session_browser, enable == 'enable', daily, weekly,
monthly, run_at, without_app)
@when(
parsers.parse('I set the backup schedule to {enable:w} for {daily:d} '
'daily, {weekly:d} weekly and {monthly:d} monthly at '
'{run_at:d}:00 without app {without_app:w}'))
def backup_schedule_set2(session_browser, enable, daily, weekly, monthly,
run_at, without_app):
_backup_schedule_set(session_browser, enable == 'enable', daily, weekly,
monthly, run_at, without_app)
@then(
parsers.parse('the schedule should be set to {enable:w} for {daily:d} '
'daily, {weekly:d} weekly and {monthly:d} monthly at '
'{run_at:d}:00 without app {without_app:w}'))
def backup_schedule_assert(session_browser, enable, daily, weekly, monthly,
run_at, without_app):
def _backup_schedule_assert(session_browser, enable, daily, weekly, monthly,
run_at, without_app):
schedule = _backup_schedule_get(session_browser)
assert schedule['enable'] == (enable == 'enable')
assert schedule['enable'] == enable
assert schedule['daily'] == daily
assert schedule['weekly'] == weekly
assert schedule['monthly'] == monthly
@ -86,65 +97,9 @@ def backup_schedule_assert(session_browser, enable, daily, weekly, monthly,
assert schedule['without_apps'][0] == without_app
def _open_main_page(browser):
with functional.wait_for_page_update(browser):
browser.find_link_by_href('/plinth/').first.click()
def _download_file_logged_in(browser, url, suffix=''):
"""Download a file from Plinth, pretend being logged in via cookies"""
if not url.startswith("http"):
current_url = urllib.parse.urlparse(browser.url)
url = "%s://%s%s" % (current_url.scheme, current_url.netloc, url)
cookies = browser.driver.get_cookies()
cookies = {cookie["name"]: cookie["value"] for cookie in cookies}
response = requests.get(url, verify=False, cookies=cookies)
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
for chunk in response.iter_content(chunk_size=128):
temp_file.write(chunk)
return temp_file.name
def _download(browser, archive_name=None):
functional.nav_to_module(browser, 'backups')
href = f'/plinth/sys/backups/root/download/{archive_name}/'
url = functional.base_url + href
file_path = _download_file_logged_in(browser, url, suffix='.tar.gz')
return file_path
def _upload_and_restore(browser, app_name, downloaded_file_path):
functional.nav_to_module(browser, 'backups')
browser.find_link_by_href('/plinth/sys/backups/upload/').first.click()
fileinput = browser.driver.find_element_by_id('id_backups-file')
fileinput.send_keys(downloaded_file_path)
# submit upload form
functional.submit(browser)
# submit restore form
with functional.wait_for_page_update(browser,
expected_url='/plinth/sys/backups/'):
functional.submit(browser)
def _backup_schedule_set(browser, enable, daily, weekly, monthly, run_at,
without_app):
"""Set the schedule for root repository."""
functional.nav_to_module(browser, 'backups')
browser.find_link_by_href(
'/plinth/sys/backups/root/schedule/').first.click()
if enable:
browser.find_by_name('backups_schedule-enabled').check()
else:
browser.find_by_name('backups_schedule-enabled').uncheck()
browser.fill('backups_schedule-daily_to_keep', daily)
browser.fill('backups_schedule-weekly_to_keep', weekly)
browser.fill('backups_schedule-monthly_to_keep', monthly)
browser.fill('backups_schedule-run_at_hour', run_at)
functional.eventually(browser.find_by_css, args=['.select-all'])
browser.find_by_css('.select-all').first.check()
browser.find_by_css(f'input[value="{without_app}"]').first.uncheck()
functional.submit(browser)
def _backup_schedule_disable(session_browser):
"""Disable schedule for the root repository."""
_backup_schedule_set(session_browser, False, 1, 2, 3, 2, 'names')
def _backup_schedule_get(browser):
@ -174,3 +129,64 @@ def _backup_schedule_get(browser):
'without_apps':
without_apps
}
def _backup_schedule_set(browser, enable, daily, weekly, monthly, run_at,
without_app):
"""Set the schedule for root repository."""
functional.nav_to_module(browser, 'backups')
browser.find_link_by_href(
'/plinth/sys/backups/root/schedule/').first.click()
if enable:
browser.find_by_name('backups_schedule-enabled').check()
else:
browser.find_by_name('backups_schedule-enabled').uncheck()
browser.fill('backups_schedule-daily_to_keep', daily)
browser.fill('backups_schedule-weekly_to_keep', weekly)
browser.fill('backups_schedule-monthly_to_keep', monthly)
browser.fill('backups_schedule-run_at_hour', run_at)
functional.eventually(browser.find_by_css, args=['.select-all'])
browser.find_by_css('.select-all').first.check()
browser.find_by_css(f'input[value="{without_app}"]').first.uncheck()
functional.submit(browser)
def _download_file_logged_in(browser, url, suffix=''):
"""Download a file from Plinth, pretend being logged in via cookies"""
if not url.startswith("http"):
current_url = urllib.parse.urlparse(browser.url)
url = "%s://%s%s" % (current_url.scheme, current_url.netloc, url)
cookies = browser.driver.get_cookies()
cookies = {cookie["name"]: cookie["value"] for cookie in cookies}
response = requests.get(url, verify=False, cookies=cookies)
with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
for chunk in response.iter_content(chunk_size=128):
temp_file.write(chunk)
return temp_file.name
def _download(browser, archive_name=None):
functional.nav_to_module(browser, 'backups')
href = f'/plinth/sys/backups/root/download/{archive_name}/'
url = functional.base_url + href
file_path = _download_file_logged_in(browser, url, suffix='.tar.gz')
return file_path
def _open_main_page(browser):
with functional.wait_for_page_update(browser):
browser.find_link_by_href('/plinth/').first.click()
def _upload_and_restore(browser, app_name, downloaded_file_path):
functional.nav_to_module(browser, 'backups')
browser.find_link_by_href('/plinth/sys/backups/upload/').first.click()
fileinput = browser.driver.find_element_by_id('id_backups-file')
fileinput.send_keys(downloaded_file_path)
# submit upload form
functional.submit(browser)
# submit restore form
with functional.wait_for_page_update(browser,
expected_url='/plinth/sys/backups/'):
functional.submit(browser)

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@system
Feature: Server Administration
Run server administration application - Cockpit.
Background:
Given I'm a logged in user
Given the cockpit application is installed
Scenario: Enable cockpit application
Given the cockpit application is disabled
When I enable the cockpit application
Then the cockpit site should be available
Scenario: Disable cockpit application
Given the cockpit application is enabled
When I disable the cockpit application
Then the cockpit site should not be available

View File

@ -3,6 +3,29 @@
Functional, browser based tests for cockpit app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('cockpit.feature')
pytestmark = [pytest.mark.system, pytest.mark.essential, pytest.mark.cockpit]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'cockpit')
yield
functional.app_disable(session_browser, 'cockpit')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'cockpit')
functional.app_enable(session_browser, 'cockpit')
assert functional.service_is_running(session_browser, 'cockpit')
assert functional.is_available(session_browser, 'cockpit')
functional.app_disable(session_browser, 'cockpit')
assert functional.service_is_not_running(session_browser, 'cockpit')
assert not functional.is_available(session_browser, 'cockpit')

View File

@ -145,6 +145,7 @@ def setup(helper, old_version=None):
"""Installs and configures module"""
helper.install(packages)
helper.install(packages_bloat, skip_recommends=True)
helper.call('post', audit.domain.repair)
helper.call('post', audit.ldap.repair)
helper.call('post', audit.spam.repair)
helper.call('post', audit.tls.repair)

View File

@ -13,8 +13,10 @@ import time
from types import SimpleNamespace
from django.core.exceptions import ValidationError
from plinth.errors import ActionError
from django.utils.translation import ugettext_lazy as _
from plinth.actions import superuser_run
from plinth.errors import ActionError
from plinth.modules.config import get_domainname
from . import models
from plinth.modules.email_server import interproc, postconf
@ -29,13 +31,153 @@ class ClientError(RuntimeError):
def get():
# Stub
return [models.Diagnosis('Email domains')]
translation_table = [
(check_postfix_domains, _('Postfix domain name config')),
]
results = []
with postconf.mutex.lock_all():
for check, title in translation_table:
results.append(check(title))
return results
def repair():
# Stub
raise RuntimeError()
superuser_run('email_server', ['-i', 'domain', 'set_up'])
def repair_component(action_name):
allowed_actions = {'set_up': ['postfix']}
if action_name not in allowed_actions:
return
superuser_run('email_server', ['-i', 'domain', action_name])
return allowed_actions[action_name]
def action_set_up():
with postconf.mutex.lock_all():
fix_postfix_domains(check_postfix_domains())
def check_postfix_domains(title=''):
diagnosis = models.MainCfDiagnosis(title, action='set_up')
domain = get_domainname() or 'localhost'
postconf_keys = (k for k in managed_keys if not k.startswith('_'))
conf = postconf.get_many_unsafe(postconf_keys, flag='-x')
dest_set = set(postconf.parse_maps(conf['mydestination']))
deletion_set = set()
temp = _amend_mailname(domain)
if temp is not None:
diagnosis.error('Set /etc/mailname to %s', temp)
diagnosis.flag('_mailname', temp)
# Amend $mydomain and conf['mydomain']
temp = _amend_mydomain(conf['mydomain'], domain)
if temp is not None:
diagnosis.error('Set $mydomain to %s', temp)
diagnosis.flag('mydomain', temp)
deletion_set.add(conf['mydomain'])
conf['mydomain'] = temp
# Amend $myhostname and conf['myhostname']
temp = _amend_myhostname(conf['myhostname'], conf['mydomain'])
if temp is not None:
diagnosis.error('Set $myhostname to %s', temp)
diagnosis.flag('myhostname', temp)
deletion_set.add(conf['myhostname'])
conf['myhostname'] = temp
# Delete old domain names
deletion_set.discard('localhost')
dest_set.difference_update(deletion_set)
# Amend $mydestination
temp = _amend_mydestination(dest_set, conf['mydomain'], conf['myhostname'],
diagnosis.error)
if temp is not None:
diagnosis.flag('mydestination', temp)
elif len(deletion_set) > 0:
corrected_value = ', '.join(sorted(dest_set))
diagnosis.error('Update $mydestination')
diagnosis.flag('mydestination', corrected_value)
return diagnosis
def _amend_mailname(domain):
with open('/etc/mailname', 'r') as fd:
mailname = fd.readline().strip()
# If mailname is not localhost, refresh it
if mailname != 'localhost':
temp = _change_to_domain_name(mailname, domain, False)
if temp != mailname:
return temp
return None
def _amend_mydomain(conf_value, domain):
temp = _change_to_domain_name(conf_value, domain, False)
if temp != conf_value:
return temp
return None
def _amend_myhostname(conf_value, mydomain):
if conf_value != mydomain:
if not conf_value.endswith('.' + mydomain):
return mydomain
return None
def _amend_mydestination(dest_set, mydomain, myhostname, error):
addition_set = set()
if mydomain not in dest_set:
error('Value of $mydomain is not in $mydestination')
addition_set.add('$mydomain')
addition_set.add('$myhostname')
if myhostname not in dest_set:
error('Value of $myhostname is not in $mydestination')
addition_set.add('$mydomain')
addition_set.add('$myhostname')
if 'localhost' not in dest_set:
error('localhost is not in $mydestination')
addition_set.add('localhost')
if addition_set:
addition_set.update(dest_set)
return ', '.join(sorted(addition_set))
return None
def _change_to_domain_name(value, domain, allow_old_fqdn):
# Detect invalid values
if not value or '.' not in value:
return domain
if not allow_old_fqdn and value != domain:
return domain
else:
return value
def fix_postfix_domains(diagnosis):
diagnosis.apply_changes(_apply_domain_changes)
def _apply_domain_changes(conf_dict):
for key, value in conf_dict.items():
if key.startswith('_'):
update = globals()['su_set' + key]
update(value)
post = {k: v for (k, v) in conf_dict.items() if not k.startswith('_')}
postconf.set_many_unsafe(post)
def get_domain_config():

View File

@ -19,7 +19,7 @@ class Diagnosis:
"""Class constructor"""
self.title = title
self.action = action
self.critical = []
self.critical_errors = []
self.errors = []
def to_json(self):
@ -29,7 +29,7 @@ class Diagnosis:
'title': self.title,
'action': self.action,
'errors': self.errors,
'critical': self.critical
'critical_errors': self.critical_errors
}
@classmethod
@ -47,15 +47,15 @@ class Diagnosis:
title = translate(title) or title
result = cls(title, action=valid_dict['action'])
result.errors.extend(valid_dict['errors'])
result.critical.extend(valid_dict['critical'])
result.critical_errors.extend(valid_dict['critical_errors'])
return result
def critical(self, message_fmt, *args):
"""Append a message to the critical errors list"""
if args:
self.critical.append(message_fmt % args)
self.critical_errors.append(message_fmt % args)
else:
self.critical.append(message_fmt)
self.critical_errors.append(message_fmt)
def error(self, message_fmt, *args):
"""Append a message to the errors list"""
@ -69,7 +69,7 @@ class Diagnosis:
if log:
self.write_logs()
if self.critical:
if self.critical_errors:
return [self.title, 'error']
elif self.errors:
return [self.title, 'failed']
@ -79,19 +79,19 @@ class Diagnosis:
@property
def has_failed(self):
"""True if the diagnosis has failed or contains an error"""
return (self.critical or self.errors)
return (self.critical_errors or self.errors)
def write_logs(self):
"""Log errors and failures"""
logger.debug('Ran audit: %s', self.title)
for message in self.critical:
for message in self.critical_errors:
logger.critical(message)
for message in self.errors:
logger.error(message)
def sorting_key(self):
"""The key function for list.sort"""
return (-len(self.critical), -len(self.errors), self.title)
return (-len(self.critical_errors), -len(self.errors), self.title)
class MainCfDiagnosis(Diagnosis):

View File

@ -61,10 +61,26 @@ def get_many(key_list):
return get_many_unsafe(key_list)
def get_many_unsafe(key_iterator):
def get_many_unsafe(key_iterator, flag=''):
result = {}
args = ['/sbin/postconf']
if flag:
args.append(flag)
number_of_keys = 0
for key in key_iterator:
result[key] = get_unsafe(key)
args.append(key)
number_of_keys += 1
stdout = _run(args)
for line in filter(None, stdout.split('\n')):
key, sep, value = line.partition('=')
if not sep:
raise ValueError('Invalid output detected')
result[key.strip()] = value.strip()
if len(result) != number_of_keys:
raise ValueError('Some keys were missing from the output')
return result

View File

@ -21,7 +21,7 @@
<li class="list-group-item clearfix">
<span>{{ model.title }}</span>
{% if model.critical %}
{% if model.critical_errors %}
<span class="badge badge-danger">{% trans "error" %}</span>
{% elif model.errors %}
<span class="badge badge-warning">{% trans "failed" %}</span>
@ -41,7 +41,7 @@
{% endif %}
<ul>
{% for message in model.critical %}
{% for message in model.critical_errors %}
<li>{{ message }}</li>
{% endfor %}
{% for message in model.errors %}

View File

@ -85,7 +85,7 @@ class EmailServerView(TabMixin, AppView):
"""Server configuration page"""
app_id = 'email_server'
template_name = 'email_server.html'
audit_modules = ('tls', 'rcube')
audit_modules = ('domain', 'tls', 'rcube')
def get_context_data(self, *args, **kwargs):
dlist = []

View File

@ -1,113 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @gitweb @sso
Feature: gitweb Simple Git Hosting
Git web interface.
Background:
Given I'm a logged in user
And the gitweb application is installed
Scenario: Enable gitweb application
Given the gitweb application is disabled
When I enable the gitweb application
Then the gitweb site should be available
Scenario: Create public repository
Given the gitweb application is enabled
And a public repository that doesn't exist
When I create the repository
Then the repository should be listed as a public
And the repository should be listed on gitweb
Scenario: Create private repository
Given the gitweb application is enabled
And a private repository that doesn't exist
When I create the repository
Then the repository should be listed as a private
And the repository should be listed on gitweb
@backups
Scenario: Backup and restore gitweb
Given the gitweb application is enabled
And a repository
When I create a backup of the gitweb app data with name test_gitweb
And I delete the repository
And I restore the gitweb app data backup with name test_gitweb
Then the repository should be restored
And the gitweb site should be available
Scenario: Public gitweb site shows only public repositories
Given the gitweb application is enabled
And both public and private repositories exist
When I log out
Then the public repository should be listed on gitweb
And the private repository should not be listed on gitweb
Scenario: Gitweb is not public if there are only private repositories
Given the gitweb application is enabled
And at least one repository exists
And all repositories are private
When I log out
And I access gitweb application
Then I should be prompted for login
And gitweb app should not be visible on the front page
Scenario: Edit repository metadata
Given the gitweb application is enabled
And a public repository that doesn't exist
And a repository metadata:
description: Test Description
owner: Test Owner
access: private
When I create the repository
And I set the metadata of the repository
Then the metadata of the repository should be as set
Scenario: Edit default branch of the repository
Given the gitweb application is enabled
And a repository with the branch branch1
When I set branch1 as a default branch
Then the gitweb site should show branch1 as a default repo branch
Scenario: Access public repository with git client
Given the gitweb application is enabled
And a public repository
When using a git client
Then the repository should be publicly readable
And the repository should not be publicly writable
And the repository should be privately writable
Scenario: Access private repository with git client
Given the gitweb application is enabled
And a private repository
When using a git client
Then the repository should not be publicly readable
And the repository should not be publicly writable
And the repository should be privately readable
And the repository should be privately writable
Scenario: User of git-access group can access gitweb site
Given the gitweb application is enabled
And all repositories are private
And the user gituser in group git-access exists
When I'm logged in as the user gituser
Then the gitweb site should be available
Scenario: User not of git-access group can't access gitweb site
Given the gitweb application is enabled
And all repositories are private
And the user nogroupuser exists
When I'm logged in as the user nogroupuser
Then the gitweb site should not be available
Scenario: Delete repository
Given the gitweb application is enabled
And a repository
When I delete the repository
Then the repository should not be listed
Scenario: Disable gitweb application
Given the gitweb application is enabled
When I disable the gitweb application
Then the gitweb site should not be available

View File

@ -17,7 +17,6 @@ REPO_DATA = {
'description': '',
'owner': '',
'access': 'private',
'default_branch': 'master',
}
@ -65,9 +64,11 @@ def test_create_repo(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 json.loads(call_action(['repo-info', '--name',
REPO_NAME])) == REPO_DATA
assert repo == REPO_DATA
assert len(default_branch) > 0
def test_change_repo_medatada(call_action, existing_repo):
@ -77,7 +78,6 @@ def test_change_repo_medatada(call_action, existing_repo):
'description': 'description2',
'owner': 'owner2',
'access': 'public',
'default_branch': 'master',
}
call_action([
@ -89,9 +89,10 @@ def test_change_repo_medatada(call_action, existing_repo):
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 json.loads(call_action(['repo-info', '--name',
REPO_NAME])) == new_data
assert repo == new_data
def test_rename_repository(call_action, existing_repo):
@ -101,21 +102,17 @@ def test_rename_repository(call_action, existing_repo):
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 json.loads(call_action(['repo-info', '--name', new_name])) == {
**REPO_DATA,
**{
'name': new_name
}
}
assert repo['name'] == new_name
def test_get_branches(call_action, existing_repo):
"""Test getting all the branches of the repository."""
assert json.loads(call_action(['get-branches', '--name', REPO_NAME])) == {
"default_branch": "master",
"branches": []
}
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):

View File

@ -2,185 +2,136 @@
"""
Functional, browser based tests for gitweb app.
"""
import contextlib
import os
import shutil
import subprocess
import tempfile
from pytest_bdd import given, parsers, scenarios, then, when
import pytest
from plinth.tests import functional
scenarios('gitweb.feature')
pytestmark = [pytest.mark.apps, pytest.mark.gitweb]
_default_url = functional.config['DEFAULT']['url']
@given('a public repository')
@given('a repository')
@given('at least one repository exists')
def gitweb_repo(session_browser):
_create_repo(session_browser, 'Test-repo', 'public', True)
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'gitweb')
functional.app_enable(session_browser, 'gitweb')
yield
functional.login(session_browser)
functional.app_disable(session_browser, 'gitweb')
@given('a private repository')
def gitweb_private_repo(session_browser):
_create_repo(session_browser, 'Test-repo', 'private', True)
@pytest.fixture(autouse=True)
def fixture_login(session_browser):
"""Login fixture."""
functional.login(session_browser)
functional.app_enable(session_browser, 'gitweb')
yield
@given(parsers.parse('a repository with the branch {branch:w}'))
def _create_repo_with_branch(session_browser, branch):
_delete_repo(session_browser, 'Test-repo', ignore_missing=True)
_create_repo(session_browser, 'Test-repo', 'public')
_create_branch('Test-repo', branch)
@given('both public and private repositories exist')
def gitweb_public_and_private_repo(session_browser):
_create_repo(session_browser, 'Test-repo', 'public', True)
_create_repo(session_browser, 'Test-repo2', 'private', True)
@given(parsers.parse("a {access:w} repository that doesn't exist"))
def gitweb_nonexistent_repo(session_browser, access):
_delete_repo(session_browser, 'Test-repo', ignore_missing=True)
return dict(access=access)
@given('all repositories are private')
def gitweb_all_repositories_private(session_browser):
def test_all_repos_private(session_browser):
"""Test repo accessability when all repos are private."""
_create_repo(session_browser, 'Test-repo', 'private', ok_if_exists=True)
_set_all_repos_private(session_browser)
if not functional.user_exists(session_browser, 'gitweb_user'):
functional.create_user(session_browser, 'gitweb_user',
groups=['git-access'])
if not functional.user_exists(session_browser, 'nogroupuser'):
functional.create_user(session_browser, 'nogroupuser', groups=[])
functional.login_with_account(session_browser, functional.base_url,
'gitweb_user')
assert functional.is_available(session_browser, 'gitweb')
assert len(functional.find_on_front_page(session_browser, 'gitweb')) == 1
functional.login_with_account(session_browser, functional.base_url,
'nogroupuser')
assert not functional.is_available(session_browser, 'gitweb')
assert len(functional.find_on_front_page(session_browser, 'gitweb')) == 0
functional.logout(session_browser)
functional.access_url(session_browser, 'gitweb')
assert functional.is_login_prompt(session_browser)
assert len(functional.find_on_front_page(session_browser, 'gitweb')) == 0
@given(parsers.parse('a repository metadata:\n{metadata}'),
target_fixture='gitweb_repo_metadata')
def gitweb_repo_metadata(session_browser, metadata):
metadata_dict = {}
for item in metadata.split('\n'):
item = item.split(': ')
metadata_dict[item[0]] = item[1]
return metadata_dict
@when('I create the repository')
def gitweb_create_repo(session_browser, access):
_create_repo(session_browser, 'Test-repo', access)
@when('I delete the repository')
def gitweb_delete_repo(session_browser):
@pytest.mark.backups
def test_backup(session_browser):
"""Test backing up and restoring."""
_create_repo(session_browser, 'Test-repo', ok_if_exists=True)
functional.backup_create(session_browser, 'gitweb', 'test_gitweb')
_delete_repo(session_browser, 'Test-repo')
functional.backup_restore(session_browser, 'gitweb', 'test_gitweb')
assert _repo_exists(session_browser, 'Test-repo')
assert functional.is_available(session_browser, 'gitweb')
@when(parsers.parse('I set {branch:w} as a default branch'))
def gitweb_set_default_branch(session_browser, branch):
_set_default_branch(session_browser, 'Test-repo', branch)
@pytest.mark.parametrize('access', ['public', 'private'])
@pytest.mark.parametrize('repo_name', ['Test-repo', 'Test-repo.git'])
def test_create_delete_repo(session_browser, access, repo_name):
"""Test creating and deleting a repo and accessing with a git client."""
_delete_repo(session_browser, repo_name, ignore_missing=True)
_create_repo(session_browser, repo_name, access)
assert _repo_exists(session_browser, repo_name, access)
assert _site_repo_exists(session_browser, repo_name)
if access == "public":
assert _repo_is_readable(repo_name)
else:
assert not _repo_is_readable(repo_name)
assert not _repo_is_writable(repo_name)
assert _repo_is_readable(repo_name, with_auth=True)
assert _repo_is_writable(repo_name, with_auth=True)
_delete_repo(session_browser, repo_name)
assert not _repo_exists(session_browser, repo_name)
@when('I set the metadata of the repository')
def gitweb_edit_repo_metadata(session_browser, gitweb_repo_metadata):
_edit_repo_metadata(session_browser, 'Test-repo', gitweb_repo_metadata)
def test_both_private_and_public_repo_exist(session_browser):
"""Tests when both private and public repo exist."""
_create_repo(session_browser, 'Test-repo', 'public', True)
_create_repo(session_browser, 'Test-repo-private', 'private', True)
@when('using a git client')
def gitweb_using_git_client():
pass
@then(
parsers.parse(
'the gitweb site should show {branch:w} as a default repo branch'))
def gitweb_site_check_default_repo_branch(session_browser, branch):
assert _get_gitweb_site_default_repo_branch(session_browser,
'Test-repo') == branch
@then('the repository should be restored')
@then('the repository should be listed as a public')
def gitweb_repo_should_exists(session_browser):
assert _repo_exists(session_browser, 'Test-repo', access='public')
@then('the repository should be listed as a private')
def gitweb_private_repo_should_exists(session_browser):
assert _repo_exists(session_browser, 'Test-repo', 'private')
@then('the repository should not be listed')
def gitweb_repo_should_not_exist(session_browser):
assert not _repo_exists(session_browser, 'Test-repo')
@then('the public repository should be listed on gitweb')
@then('the repository should be listed on gitweb')
def gitweb_repo_should_exist_on_gitweb(session_browser):
functional.logout(session_browser)
assert _site_repo_exists(session_browser, 'Test-repo')
assert not _site_repo_exists(session_browser, 'Test-repo-private')
@then('the private repository should not be listed on gitweb')
def gitweb_private_repo_should_exists_on_gitweb(session_browser):
assert not _site_repo_exists(session_browser, 'Test-repo2')
def test_edit_repo_metadata(session_browser):
"""Test edit repo metadata."""
_create_repo(session_browser, 'Test-repo2', 'public', ok_if_exists=True)
_delete_repo(session_browser, 'Test-repo', ignore_missing=True)
repo_metadata = {
'name': 'Test-repo',
'description': 'Test Description',
'owner': 'Test Owner',
'access': 'private',
}
_edit_repo_metadata(session_browser, 'Test-repo2', repo_metadata)
assert _get_repo_metadata(session_browser, "Test-repo") == repo_metadata
_create_branch('Test-repo', 'branch1')
_set_default_branch(session_browser, 'Test-repo', 'branch1')
assert _get_gitweb_site_default_repo_branch(session_browser,
'Test-repo') == 'branch1'
@then('the metadata of the repository should be as set')
def gitweb_repo_metadata_should_match(session_browser, gitweb_repo_metadata):
actual_metadata = _get_repo_metadata(session_browser, 'Test-repo')
assert all(item in actual_metadata.items()
for item in gitweb_repo_metadata.items())
def test_enable_disable(session_browser):
"""Test enabling and disabling the app."""
functional.app_disable(session_browser, 'gitweb')
assert not functional.is_available(session_browser, 'gitweb')
@then('the repository should be publicly readable')
def gitweb_repo_publicly_readable():
assert _repo_is_readable('Test-repo')
assert _repo_is_readable('Test-repo', url_git_extension=True)
@then('the repository should not be publicly readable')
def gitweb_repo_not_publicly_readable():
assert not _repo_is_readable('Test-repo')
assert not _repo_is_readable('Test-repo', url_git_extension=True)
@then('the repository should not be publicly writable')
def gitweb_repo_not_publicly_writable():
assert not _repo_is_writable('Test-repo')
assert not _repo_is_writable('Test-repo', url_git_extension=True)
@then('the repository should be privately readable')
def gitweb_repo_privately_readable():
assert _repo_is_readable('Test-repo', with_auth=True)
assert _repo_is_readable('Test-repo', with_auth=True,
url_git_extension=True)
@then('the repository should be privately writable')
def gitweb_repo_privately_writable():
assert _repo_is_writable('Test-repo', with_auth=True)
assert _repo_is_writable('Test-repo', with_auth=True,
url_git_extension=True)
def _create_branch(repo, branch):
"""Create a branch on the remote repository."""
repo_url = _get_repo_url(repo, with_auth=True)
with _gitweb_temp_directory() as temp_directory:
repo_path = os.path.join(temp_directory, repo)
_create_local_repo(repo_path)
add_branch_commands = [['git', 'checkout', '-q', '-b', branch],
[
'git', '-c', 'user.name=Tester', '-c',
'user.email=tester', 'commit', '-q',
'--allow-empty', '-m', 'test_branch1'
],
['git', 'push', '-q', '-f', repo_url, branch]]
for command in add_branch_commands:
subprocess.check_call(command, cwd=repo_path)
functional.app_enable(session_browser, 'gitweb')
assert functional.is_available(session_browser, 'gitweb')
def _create_local_repo(path):
@ -200,7 +151,7 @@ def _create_repo(browser, repo, access=None, ok_if_exists=False):
"""Create repository."""
if not _repo_exists(browser, repo, access):
_delete_repo(browser, repo, ignore_missing=True)
browser.find_link_by_href('/plinth/apps/gitweb/create/').first.click()
browser.links.find_by_href('/plinth/apps/gitweb/create/').first.click()
browser.find_by_id('id_gitweb-name').fill(repo)
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
@ -211,10 +162,32 @@ def _create_repo(browser, repo, access=None, ok_if_exists=False):
assert False, 'Repo already exists.'
def _create_branch(repo, branch):
"""Add a branch to the repo."""
repo_url = _get_repo_url(repo, with_auth=True)
with _gitweb_temp_directory() as temp_directory:
repo_path = os.path.join(temp_directory, repo)
_create_local_repo(repo_path)
add_branch_commands = [['git', 'checkout', '-q', '-b', branch],
[
'git', '-c', 'user.name=Tester', '-c',
'user.email=tester', 'commit', '-q',
'--allow-empty', '-m', 'test_branch1'
],
['git', 'push', '-q', '-f', repo_url, branch]]
for command in add_branch_commands:
subprocess.check_call(command, cwd=repo_path)
def _delete_repo(browser, repo, ignore_missing=False):
"""Delete repository."""
functional.nav_to_module(browser, 'gitweb')
delete_link = browser.find_link_by_href(
if repo.endswith('.git'):
repo = repo[:-4]
delete_link = browser.links.find_by_href(
'/plinth/apps/gitweb/{}/delete/'.format(repo))
if delete_link or not ignore_missing:
delete_link.first.click()
@ -224,20 +197,15 @@ def _delete_repo(browser, repo, ignore_missing=False):
def _edit_repo_metadata(browser, repo, metadata):
"""Set repository metadata."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
if 'name' in metadata:
browser.find_by_id('id_gitweb-name').fill(metadata['name'])
if 'description' in metadata:
browser.find_by_id('id_gitweb-description').fill(
metadata['description'])
if 'owner' in metadata:
browser.find_by_id('id_gitweb-owner').fill(metadata['owner'])
if 'access' in metadata:
if metadata['access'] == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
browser.find_by_id('id_gitweb-name').fill(metadata['name'])
browser.find_by_id('id_gitweb-description').fill(metadata['description'])
browser.find_by_id('id_gitweb-owner').fill(metadata['owner'])
if metadata['access'] == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
functional.submit(browser)
@ -251,7 +219,7 @@ def _get_gitweb_site_default_repo_branch(browser, repo):
def _get_repo_metadata(browser, repo):
"""Get repository metadata."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
metadata = {}
for item in ['name', 'description', 'owner']:
@ -278,6 +246,22 @@ def _get_repo_url(repo, with_auth):
scheme, functional.config['DEFAULT']['username'], password, url, repo)
def _gitweb_git_command_is_successful(command, cwd):
"""Check if a command runs successfully or gives authentication error"""
# Tell OS not to translate command return messages
env = os.environ.copy()
env['LC_ALL'] = 'C'
process = subprocess.run(command, capture_output=True, cwd=cwd, env=env,
check=False)
if process.returncode != 0:
if 'Authentication failed' in process.stderr.decode():
return False
print(process.stdout.decode())
process.check_returncode() # Raise exception
return True
@contextlib.contextmanager
def _gitweb_temp_directory():
"""Create temporary directory"""
@ -286,26 +270,12 @@ def _gitweb_temp_directory():
shutil.rmtree(name)
def _gitweb_git_command_is_successful(command, cwd):
"""Check if a command runs successfully or gives authentication error"""
# Tell OS not to translate command return messages
env = os.environ.copy()
env['LC_ALL'] = 'C'
process = subprocess.run(command, capture_output=True, cwd=cwd, env=env)
if process.returncode != 0:
if 'Authentication failed' in process.stderr.decode():
return False
print(process.stdout.decode())
# raise exception
process.check_returncode()
return True
def _repo_exists(browser, repo, access=None):
"""Check whether the repository exists."""
functional.nav_to_module(browser, 'gitweb')
links_found = browser.find_link_by_href('/gitweb/{}.git'.format(repo))
if not repo.endswith('.git'):
repo = repo + ".git"
links_found = browser.links.find_by_href('/gitweb/{}'.format(repo))
access_matches = True
if links_found and access:
parent = links_found.first.find_by_xpath('..').first
@ -317,53 +287,27 @@ def _repo_exists(browser, repo, access=None):
return bool(links_found) and access_matches
def _repo_is_readable(repo, with_auth=False, url_git_extension=False):
def _repo_is_readable(repo, with_auth=False):
"""Check if a git repo is readable with git client."""
url = _get_repo_url(repo, with_auth)
if url_git_extension:
url = url + '.git'
git_command = ['git', 'clone', '-c', 'http.sslverify=false', url]
with _gitweb_temp_directory() as cwd:
return _gitweb_git_command_is_successful(git_command, cwd)
def _repo_is_writable(repo, with_auth=False, url_git_extension=False):
def _repo_is_writable(repo, with_auth=False):
"""Check if a git repo is writable with git client."""
url = _get_repo_url(repo, with_auth)
if url_git_extension:
url = url + '.git'
with _gitweb_temp_directory() as temp_directory:
repo_directory = os.path.join(temp_directory, 'test-project')
_create_local_repo(repo_directory)
git_push_command = ['git', 'push', '-qf', url, 'master']
git_push_command = [
'git', '-c', 'push.default=current', 'push', '-qf', url
]
return _gitweb_git_command_is_successful(git_push_command,
repo_directory)
def _set_default_branch(browser, repo, branch):
"""Set default branch of the repository."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
browser.find_by_id('id_gitweb-default_branch').select(branch)
functional.submit(browser)
def _set_repo_access(browser, repo, access):
"""Set repository as public or private."""
functional.nav_to_module(browser, 'gitweb')
browser.find_link_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
functional.submit(browser)
def _set_all_repos_private(browser):
"""Set all repositories private"""
functional.nav_to_module(browser, 'gitweb')
@ -376,7 +320,30 @@ def _set_all_repos_private(browser):
_set_repo_access(browser, repo, 'private')
def _set_default_branch(browser, repo, branch):
"""Set default branch of the repository."""
functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
browser.find_by_id('id_gitweb-default_branch').select(branch)
functional.submit(browser)
def _set_repo_access(browser, repo, access):
"""Set repository as public or private."""
functional.nav_to_module(browser, 'gitweb')
browser.links.find_by_href(
'/plinth/apps/gitweb/{}/edit/'.format(repo)).first.click()
if access == 'private':
browser.find_by_id('id_gitweb-is_private').check()
else:
browser.find_by_id('id_gitweb-is_private').uncheck()
functional.submit(browser)
def _site_repo_exists(browser, repo):
"""Check whether the repository exists on Gitweb site."""
browser.visit('{}/gitweb'.format(_default_url))
return browser.find_by_css('a[href="/gitweb/{0}.git"]'.format(repo))
if not repo.endswith('.git'):
repo = repo + ".git"
return bool(browser.find_by_css('a[href="/gitweb/{0}"]'.format(repo)))

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @i2p
Feature: I2P Anonymity Network
Manage I2P configuration.
Background:
Given I'm a logged in user
Given the i2p application is installed
Scenario: Enable i2p application
Given the i2p application is disabled
When I enable the i2p application
Then the i2p service should be running
Scenario: Disable i2p application
Given the i2p application is enabled
When I disable the i2p application
Then the i2p service should not be running

View File

@ -3,6 +3,29 @@
Functional, browser based tests for i2p app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('i2p.feature')
pytestmark = [pytest.mark.apps, pytest.mark.i2p]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'i2p')
yield
functional.app_disable(session_browser, 'i2p')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'i2p')
functional.app_enable(session_browser, 'i2p')
assert functional.service_is_running(session_browser, 'i2p')
assert functional.is_available(session_browser, 'i2p')
functional.app_disable(session_browser, 'i2p')
assert functional.service_is_not_running(session_browser, 'i2p')
assert not functional.is_available(session_browser, 'i2p')

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @infinoted
Feature: Infinoted Collaborative Text Editor
Run Gobby Server - Infinoted
Background:
Given I'm a logged in user
Given the infinoted application is installed
Scenario: Enable infinoted application
Given the infinoted application is disabled
When I enable the infinoted application
Then the infinoted service should be running
Scenario: Disable infinoted application
Given the infinoted application is enabled
When I disable the infinoted application
Then the infinoted service should not be running

View File

@ -3,6 +3,27 @@
Functional, browser based tests for infinoted app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('infinoted.feature')
pytestmark = [pytest.mark.apps, pytest.mark.infinoted]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'infinoted')
yield
functional.app_disable(session_browser, 'infinoted')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'infinoted')
functional.app_enable(session_browser, 'infinoted')
assert functional.service_is_running(session_browser, 'infinoted')
functional.app_disable(session_browser, 'infinoted')
assert functional.service_is_not_running(session_browser, 'infinoted')

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @jsxc
Feature: JSXC XMPP Client
Run the JSXC XMPP client.
Background:
Given I'm a logged in user
Scenario: Install jsxc application
Given the jsxc application is installed
Then the jsxc site should be available
@backups
Scenario: Backup and restore jsxc
Given the jsxc application is installed
When I create a backup of the jsxc app data with name test_jsxc
And I restore the jsxc app data backup with name test_jsxc
Then the jsxc site should be available

View File

@ -3,6 +3,27 @@
Functional, browser based tests for jsxc app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('jsxc.feature')
pytestmark = [pytest.mark.apps, pytest.mark.jsxc]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login."""
functional.login(session_browser)
def test_install(session_browser):
"""Test installing the app."""
functional.install(session_browser, 'jsxc')
assert functional.is_available(session_browser, 'jsxc')
@pytest.mark.backups
def test_backup(session_browser):
"""Test backing up and restoring."""
functional.backup_create(session_browser, 'jsxc', 'test_jsxc')
functional.backup_restore(session_browser, 'jsxc', 'test_jsxc')
assert functional.is_available(session_browser, 'jsxc')

View File

@ -1,21 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @matrixsynapse
Feature: Matrix Synapse VoIP and Chat Server
Run Matrix Synapse server
Background:
Given I'm a logged in user
Given the domain name is set to mydomain.example
Given the matrixsynapse application is installed
Given the domain name for matrixsynapse is set to mydomain.example
Scenario: Enable matrixsynapse application
Given the matrixsynapse application is disabled
When I enable the matrixsynapse application
Then the matrixsynapse service should be running
Scenario: Disable matrixsynapse application
Given the matrixsynapse application is enabled
When I disable the matrixsynapse application
Then the matrixsynapse service should not be running

View File

@ -3,6 +3,30 @@
Functional, browser based tests for matrixsynapse app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('matrixsynapse.feature')
pytestmark = [pytest.mark.apps, pytest.mark.matrixsynapse]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.set_domain_name(session_browser, 'mydomain.example')
functional.install(session_browser, 'matrixsynapse')
functional.app_select_domain_name(session_browser, 'matrixsynapse',
'mydomain.example')
yield
functional.app_disable(session_browser, 'matrixsynapse')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'matrixsynapse')
functional.app_enable(session_browser, 'matrixsynapse')
assert functional.service_is_running(session_browser, 'matrixsynapse')
functional.app_disable(session_browser, 'matrixsynapse')
assert functional.service_is_not_running(session_browser, 'matrixsynapse')

View File

@ -18,7 +18,7 @@ from plinth.modules.firewall.components import Firewall
from . import manifest
version = 9
version = 10
managed_packages = ['mediawiki', 'imagemagick', 'php-sqlite3']

View File

@ -44,3 +44,11 @@ $wgDefaultSkin = "timeless";
# Domain Name
$wgServer = "https://freedombox.local";
# Enable default extensions
wfLoadExtension( 'Cite' );
wfLoadExtension( 'Interwiki' );
wfLoadExtension( 'MultimediaViewer' );
wfLoadExtension( 'Renameuser' );
wfLoadExtension( 'VisualEditor' );
wfLoadExtension( 'WikiEditor' );

View File

@ -15,7 +15,9 @@ backup = {
'files': ['/etc/mediawiki/FreedomBoxSettings.php']
},
'data': {
'directories': ['/var/lib/mediawiki-db/']
'directories': [
'/var/lib/mediawiki-db/', '/var/lib/mediawiki/images/'
]
},
'services': ['mediawiki-jobrunner']
}

View File

@ -67,12 +67,15 @@ Scenario: Upload SVG image
@backups
Scenario: Backup and restore mediawiki
Given the mediawiki application is enabled
And I ensure that there is Noise.png image with credentials admin and whatever123
When I create a backup of the mediawiki app data with name test_mediawiki
When I enable mediawiki public registrations
And I delete the mediawiki main page
And I enable mediawiki public registrations
And I delete Noise.png image with credentials admin and whatever123
And I delete the mediawiki main page with credentials admin and whatever123
And I restore the mediawiki app data backup with name test_mediawiki
Then the mediawiki main page should be restored
Then the mediawiki site should allow creating accounts
And there should be Noise.png image
And the mediawiki site should allow creating accounts
Scenario: Disable mediawiki application
Given the mediawiki application is enabled

View File

@ -6,10 +6,10 @@ Functional, browser based tests for mediawiki app.
import pathlib
from urllib.parse import urlparse
from pytest_bdd import given, parsers, scenarios, then, when
import requests
from plinth.tests import functional
from plinth.tests.functional import config
from pytest_bdd import given, parsers, scenarios, then, when
scenarios('mediawiki.feature')
@ -76,9 +76,18 @@ def login_to_mediawiki_with_credentials(session_browser, username, password):
_login_with_credentials(session_browser, username, password)
@when('I delete the mediawiki main page')
def mediawiki_delete_main_page(session_browser):
_delete_main_page(session_browser)
@when(
parsers.parse('I delete the mediawiki main page with credentials '
'{username:w} and {password:w}'))
def mediawiki_delete_main_page(session_browser, username, password):
_delete_main_page(session_browser, username, password)
@when(
parsers.parse('I delete {image:S} image with credentials '
'{username:w} and {password:w}'))
def delete_image(session_browser, username, password, image):
_delete_image(session_browser, username, password, image)
@then('the mediawiki main page should be restored')
@ -94,10 +103,17 @@ def upload_image(session_browser, username, password, image):
_upload_image(session_browser, username, password, image)
@given(
parsers.parse('I ensure that there is {image:S} image with credentials '
'{username:w} and {password:w}'))
def ensure_image_exists(session_browser, username, password, image):
if not _image_exists(session_browser, image):
_upload_image(session_browser, username, password, image)
@then(parsers.parse('there should be {image:S} image'))
def uploaded_image_should_be_available(session_browser, image):
uploaded_image = _get_uploaded_image(session_browser, image)
assert image.lower() == uploaded_image.lower()
assert _image_exists(session_browser, image)
def _enable_public_registrations(browser):
@ -137,30 +153,35 @@ def _set_admin_password(browser, password):
functional.submit(browser, form_class='form-configuration')
def _verify_create_account_link(browser):
def _is_create_account_available(browser):
"""Load the create account page and return whether creating is allowed."""
functional.visit(browser, '/mediawiki/index.php/Special:CreateAccount')
assert functional.eventually(browser.is_element_present_by_id,
args=['wpCreateaccount'])
return browser.is_element_present_by_id('wpCreateaccount')
def _verify_create_account_link(browser):
assert functional.eventually(_is_create_account_available, args=[browser])
def _verify_no_create_account_link(browser):
functional.visit(browser, '/mediawiki/index.php/Special:CreateAccount')
assert functional.eventually(browser.is_element_not_present_by_id,
args=['wpCreateaccount'])
assert functional.eventually(
lambda: not _is_create_account_available(browser))
def _is_anonymouse_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):
functional.visit(browser, '/mediawiki')
assert functional.eventually(browser.is_element_present_by_id,
args=['ca-nstab-main'])
assert functional.eventually(_is_anonymouse_read_allowed, args=[browser])
def _verify_no_anonymous_reads_edits_link(browser):
functional.visit(browser, '/mediawiki')
assert functional.eventually(browser.is_element_not_present_by_id,
args=['ca-nstab-main'])
assert functional.eventually(browser.is_element_present_by_id,
args=['ca-nstab-special'])
assert functional.eventually(
lambda: not _is_anonymouse_read_allowed(browser))
assert browser.is_element_present_by_id('ca-nstab-special')
def _login(browser, username, password):
@ -179,7 +200,7 @@ def _login_with_credentials(browser, username, password):
args=['t-upload'])
def _upload_image(browser, username, password, image):
def _upload_image(browser, username, password, image, ignore_warnings=True):
"""Upload an image to MediaWiki. Idempotent."""
functional.visit(browser, '/mediawiki')
_login(browser, username, password)
@ -187,25 +208,43 @@ def _upload_image(browser, username, password, image):
# Upload file
functional.visit(browser, '/mediawiki/Special:Upload')
file_path = pathlib.Path(__file__).parent
file_path /= '../../../../static/themes/default/img/' + image
file_path /= '../../../../static/themes/default/img/' + image.lower()
browser.attach_file('wpUploadFile', str(file_path.resolve()))
if ignore_warnings: # allow uploading file with the same name
browser.find_by_name('wpIgnoreWarning').first.click()
functional.submit(browser, element=browser.find_by_name('wpUpload')[0])
def _delete_image(browser, username, password, image):
"""Delete an image from MediaWiki."""
_login(browser, username, password)
path = f'/mediawiki/index.php?title=File:{image}&action=delete'
functional.visit(browser, path)
delete_button = browser.find_by_id('mw-filedelete-submit')
functional.submit(browser, element=delete_button)
def _get_number_of_uploaded_images(browser):
functional.visit(browser, '/mediawiki/Special:ListFiles')
return len(browser.find_by_css('.TablePager_col_img_timestamp'))
def _get_uploaded_image(browser, image):
def _image_exists(browser, image):
"""Check whether the given image exists."""
functional.visit(browser, '/mediawiki/Special:ListFiles')
elements = browser.find_link_by_partial_href(image)
return elements[0].value
if not elements: # Necessary but insufficient check.
# Special:ListFiles also shows deleted images.
return False
# The second hyperlink is a direct link to the image.
response = requests.get(elements[1]['href'], verify=False)
return response.status_code != 404
def _delete_main_page(browser):
def _delete_main_page(browser, username, password):
"""Delete the mediawiki main page."""
_login(browser, 'admin', 'whatever123')
_login(browser, username, password)
functional.visit(browser,
'/mediawiki/index.php?title=Main_Page&action=delete')
with functional.wait_for_page_update(browser):

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @minetest
Feature: Minetest Block Sandbox
Run the Minetest server
Background:
Given I'm a logged in user
Given the minetest application is installed
Scenario: Enable minetest application
Given the minetest application is disabled
When I enable the minetest application
Then the minetest service should be running
Scenario: Disable minetest application
Given the minetest application is enabled
When I disable the minetest application
Then the minetest service should not be running

View File

@ -3,6 +3,27 @@
Functional, browser based tests for minetest app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('minetest.feature')
pytestmark = [pytest.mark.apps, pytest.mark.minetest]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'minetest')
yield
functional.app_disable(session_browser, 'minetest')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'minetest')
functional.app_enable(session_browser, 'minetest')
assert functional.service_is_running(session_browser, 'minetest')
functional.app_disable(session_browser, 'minetest')
assert functional.service_is_not_running(session_browser, 'minetest')

View File

@ -1,19 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@apps @minidlna
Feature: minidlna Simple Media Server
Run miniDLNA media server
Background:
Given I'm a logged in user
And the minidlna application is installed
Scenario: Enable minidlna application
Given the minidlna application is disabled
When I enable the minidlna application
Then the minidlna service should be running
Scenario: Disable minidlna application
Given the minidlna application is enabled
When I disable the minidlna application
Then the minidlna service should not be running

View File

@ -3,6 +3,27 @@
Functional, browser based tests for minidlna app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('minidlna.feature')
pytestmark = [pytest.mark.apps, pytest.mark.minidlna]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'minidlna')
yield
functional.app_disable(session_browser, 'minidlna')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'minidlna')
functional.app_enable(session_browser, 'minidlna')
assert functional.service_is_running(session_browser, 'minidlna')
functional.app_disable(session_browser, 'minidlna')
assert functional.service_is_not_running(session_browser, 'minidlna')

View File

@ -1,20 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
@system @performance
Feature: Performance - system monitoring
Run the Performance Co-Pilot app.
Background:
Given I'm a logged in user
And advanced mode is on
And the performance application is installed
Scenario: Enable performance application
Given the performance application is disabled
When I enable the performance application
Then the performance service should be running
Scenario: Disable performance application
Given the performance application is enabled
When I disable the performance application
Then the performance service should not be running

View File

@ -3,6 +3,27 @@
Functional, browser based tests for performance app.
"""
from pytest_bdd import scenarios
import pytest
from plinth.tests import functional
scenarios('performance.feature')
pytestmark = [pytest.mark.system, pytest.mark.performance]
@pytest.fixture(scope='module', autouse=True)
def fixture_background(session_browser):
"""Login and install the app."""
functional.login(session_browser)
functional.install(session_browser, 'performance')
yield
functional.app_disable(session_browser, 'performance')
def test_enable_disable(session_browser):
"""Test enabling the app."""
functional.app_disable(session_browser, 'performance')
functional.app_enable(session_browser, 'performance')
assert functional.service_is_running(session_browser, 'performance')
functional.app_disable(session_browser, 'performance')
assert functional.service_is_not_running(session_browser, 'performance')

View File

@ -5,6 +5,12 @@ Django settings for test modules.
import os
# Workaround for django-simple-captcha 0.5.6 not being compatible with
# Django 3.2. 0.5.14 is almost there in Debian. Workaround only until then.
import django.utils.encoding
django.utils.encoding.python_2_unicode_compatible = lambda x: x
TEST_DATA_DIR = os.path.dirname(os.path.abspath(__file__))
AXES_ENABLED = False

View File

@ -22,6 +22,10 @@ logger = logging.getLogger(__name__)
def init(read_only=False):
"""Setup Django configuration in the absence of .settings file"""
# Workaround for django-simple-captcha 0.5.6 not being compatible with
# Django 3.2. 0.5.14 is almost there in Debian. Workaround only until then.
django.utils.encoding.python_2_unicode_compatible = lambda x: x
if cfg.secure_proxy_ssl_header:
settings.SECURE_PROXY_SSL_HEADER = (cfg.secure_proxy_ssl_header,
'https')

View File

@ -7,6 +7,7 @@ markers = functional
bepasty
bind
calibre
cockpit
config
coturn
datetime
@ -52,3 +53,4 @@ markers = functional
ttrss
upgrades
users
zoph

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB