Compare commits

...

30 Commits

Author SHA1 Message Date
James Valleroy
54eb4b65c6
Release v25.9.3+deb13u1 to trixie
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-12-18 08:53:28 -05:00
Sunil Mohan Adapa
8abd34c501
backups: Set proper permissions for backups-data directory
Fixes: #2554

- Update permissions on the backups-data directory so that files are only
accessible by root users.

- Ensure that the directory is created by the 'backups' app and not by each of
the apps that take the backup.

Tests:

- Run functional tests for miniflux, dynamicdns, wordpress, zoph, and nextlcoud.
There was an unrelated functional test case failure in nextcloud.

- On a fresh installation, apply patch. Service is restarted. The directory is
created with proper permissions and ownership.

- On a fresh installation, without the patch. Backup the dynamicdns app. The
directory is created with incorrect permissions. Apply the patch. Service is
restarted. Proper permissions are set on the directory.

- On a setup with incorrect permissions, re-run backups app's setup. The
permissions are updated correctly.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-12-18 08:42:07 -05:00
James Valleroy
f474da6e46
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-08-02 08:05:32 -04:00
Sunil Mohan Adapa
24be10cfd9
distupgrade: Update Trixie's release date as announced
Tests:

- Distribution upgrade page shows the updated date.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-08-01 20:03:47 -04:00
Sunil Mohan Adapa
1ae55377ea
distupgrade: Handle comments in sources.list file
Tests:

- Add a comment and /etc/apt/sources.list file. Distribution upgrade page does
not load and fails with an error.

- With the patch, page loads properly. Distribution upgrade can be triggered.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
[jvalleroy: Fix test for release date]
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-08-01 20:03:31 -04:00
James Valleroy
c639bb0d14
Release v25.9.3 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-07-21 19:30:22 -04:00
Priit Jõerüüt
93111ac0a5
Translated using Weblate (Estonian)
Currently translated at 1.3% (25 of 1854 strings)
2025-07-21 18:57:20 -04:00
109247019824
ba0c2c4530
Translated using Weblate (Bulgarian)
Currently translated at 55.5% (1029 of 1854 strings)
2025-07-21 18:57:13 -04:00
Sunil Mohan Adapa
e5eaaacb60
email: Start servers during re-setup if they are not running
- This helps during distribution upgrade from dovecot 2.3 to 2.4. Dovecot will
stop running due to dovecot server 2.4 not understanding version 2.3
configuration files. When setup is re-run, starting the daemons again is the
right thing to do.

Tests:

- With email app installed, upgrade from bookworm to trixie. Dovecot is stopped
during distribution upgrade but after freedombox service runs, it recovers and
starts running again.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2025-07-21 18:57:04 -04:00
Benedek Nagy
c5ec10d9cb
email: Add support for Dovecot 2.4
Sunil:

- When dovecot package is upgrade from 2.3 to 2.4 during distribution upgrade,
automatically re-run setup.

- Upgrade existing setups to new scheme by re-running setup with incremented app
version.

- Don't query dovecot version during app initialization. Instead overwrite the
DropinConfigs component to query dovecot version during setup and enable
operations.

- Use apt.Cache() to retrieve the installed version of dovecot package. Use
plinth.utils.Version to parse the version and perform a comparison.

- Split even configuration files that have not changed for simplicity.

- Add/update links in Dovecot configuration files.

Tests:

- Install email app on a testing container. Ensure that all files in
/etc/dovecot/conf.d/ are linked properly to 2.4 versions. TLS configuration is
accurate. Use Sogo to test login and sending mails.

  - User with LDAP account and correct password is able to login.

  - User without LDAP account or incorrect password is unable to login.

  - Send mail with Sogo to another account on the server. Notice that mails are
  stored in /var/mail/{user}/mail/ with mail:mail ownership in mbox format.

  - Logging in with email such as user@example.com works. Capital letters are
  allowed.

  - "Archive", "Drafts", "Sent", "Junk", "Trash" folders are automatically
  created and are marked with special flags. Creating additional folders such
  as "Sent Items" also results in them having special flags.

  - Thunderbird is able to connect via SSL with a self-signed certificate
  exception.

  - When an example spam message is sent, it is automatically moved to "Junk"
  folder after getting marked by rspamd.

  - When a message is moved to Junk folder, it is learned as spam by rspamd as
  seen in its admin console.

  - When a message is moved out of Junk folder (to other than "Trash" folder),
  it is learned as not-spam by rspamd as seen in its admin console.

- Install email app on a stable container with patches. Ensure that all files in
/etc/dovecot/conf.d/ are linked properly to 2.3 versions. TLS configuration is
accurate. Use Sogo to test login and sending mails.

- Install email app on a stable container without patches. Apply patches. Ensure
that all files in /etc/dovecot/conf.d/ are linked properly to 2.3 versions. TLS
configuration is accurate for dovecot 2.3. Use Sogo to test login and sending
mails. Perform distribution upgrade to testing. Ensure that all files in
/etc/dovecot/conf.d/ are linked properly to 2.3 versions. TLS configuration is
accurate for dovecot 2.4. Use Sogo to test login and sending mails.

Signed-off-by: Benedek Nagy <contact@nbenedek.me>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2025-07-21 18:56:52 -04:00
Sunil Mohan Adapa
f1e4144bd7
config: Allow overriding target path in dropin config component
- To be used when configuration has to change based on the package version.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2025-07-21 18:56:45 -04:00
Benedek Nagy
fe83245d01
sogo: Fix typo in configuration for sieve server
Signed-off-by: Benedek Nagy <contact@nbenedek.me>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2025-07-19 07:28:58 -04:00
தமிழ்நேரம்
ae33c1c238
Translated using Weblate (Tamil)
Currently translated at 91.8% (1703 of 1854 strings)
2025-07-19 07:17:39 -04:00
kosagi
4405fa07f1
Translated using Weblate (Catalan)
Currently translated at 36.1% (670 of 1854 strings)
2025-07-19 07:17:17 -04:00
Besnik Bleta
ca7e304481
Translated using Weblate (Albanian)
Currently translated at 99.5% (1846 of 1854 strings)
2025-07-19 07:17:03 -04:00
J AK
6f2ce5476d
Translated using Weblate (Albanian)
Currently translated at 99.5% (1846 of 1854 strings)
2025-07-19 07:16:52 -04:00
James Valleroy
917fc97083
Release v25.9.2 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-06-23 21:14:31 -04:00
James Valleroy
4b15d6eb20
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-06-23 21:13:32 -04:00
James Valleroy
c9d27ffedb
debian: Set the branch for trixie
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-06-23 20:54:17 -04:00
Priit Jõerüüt
c14be44c8a
Translated using Weblate (Estonian)
Currently translated at 1.2% (24 of 1854 strings)
2025-06-21 08:42:37 -04:00
James Valleroy
d7d4958e8b
performance: Handle install for trixie
In trixie, cockpit-pcp is replaced by cockpit-bridge. However, our
packages module does not properly handle virtual packages.

- Specify cockpit-bridge and pcp as dependencies. In bookworm, they were
  dependencies of cockpit-pcp.

- Allow cockpit-bridge as a substitute for cockpit-pcp.

Tests:

- In stable container, install Performance app. Install succeeds and app
  is available.

- In testing container, install Performance app. Install succeeds and
  app is available.

- Build stable-backports package with new version. Install in stable VM.
  Install Performance app. Check that dist-upgrade succeeds. After
  dist-upgrade, Performance app is still working. Uninstalling
  Performance app works. Installing Performance app works. Diagnostics
  are all passed.

Note: There is one minor issue with the Diagnostics. Package
cockpit-bridge line is shown twice (both are passed).

Fixes: #2475

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2025-06-21 08:42:28 -04:00
James Valleroy
1b5a45560f
debian: Update debconf Portuguese translation
Thanks to Américo Monteiro for the patch.
2025-06-16 19:11:15 -04:00
ikmaak
1f4ad926c6
Translated using Weblate (Dutch)
Currently translated at 97.3% (1804 of 1854 strings)
2025-06-14 09:14:29 -04:00
ikmaak
24a35018d4
Translated using Weblate (German)
Currently translated at 98.0% (1818 of 1854 strings)
2025-06-14 09:14:22 -04:00
ikmaak
f7a0a9ae80
Translated using Weblate (Dutch)
Currently translated at 95.6% (1774 of 1854 strings)
2025-06-14 09:14:13 -04:00
Priit Jõerüüt
e8303b9236
Translated using Weblate (Estonian)
Currently translated at 0.4% (9 of 1854 strings)
2025-06-14 09:14:05 -04:00
András Szűcs
9a27d64fd4
Translated using Weblate (Hungarian)
Currently translated at 72.0% (1336 of 1854 strings)
2025-06-14 09:13:54 -04:00
Priit Jõerüüt
3818a929ab
Added translation using Weblate (Estonian) 2025-06-14 09:13:40 -04:00
James Valleroy
d3f879a4b2
Release v25.9.1 to unstable
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-06-02 20:17:01 -04:00
James Valleroy
d982c63d90
doc: Fetch latest manual
Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
2025-06-02 20:15:25 -04:00
69 changed files with 10440 additions and 496 deletions

80
debian/changelog vendored
View File

@ -1,3 +1,83 @@
freedombox (25.9.3+deb13u1) trixie; urgency=medium
[ Sunil Mohan Adapa ]
* distupgrade: Handle comments in sources.list file
* distupgrade: Update Trixie's release date as announced
* backups: Set proper permissions for backups-data directory (CVE-2025-68462)
[ James Valleroy ]
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Thu, 18 Dec 2025 08:48:51 -0500
freedombox (25.9.3) unstable; urgency=medium
[ J AK ]
* Translated using Weblate (Albanian)
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
[ kosagi ]
* Translated using Weblate (Catalan)
[ தமிழ்நேரம் ]
* Translated using Weblate (Tamil)
[ Benedek Nagy ]
* sogo: Fix typo in configuration for sieve server
* email: Add support for Dovecot 2.4
[ Sunil Mohan Adapa ]
* config: Allow overriding target path in dropin config component
* email: Start servers during re-setup if they are not running
[ 109247019824 ]
* Translated using Weblate (Bulgarian)
[ Priit Jõerüüt ]
* Translated using Weblate (Estonian)
-- James Valleroy <jvalleroy@mailbox.org> Mon, 21 Jul 2025 19:29:32 -0400
freedombox (25.9.2) unstable; urgency=medium
[ Priit Jõerüüt ]
* Added translation using Weblate (Estonian)
* Translated using Weblate (Estonian)
[ András Szűcs ]
* Translated using Weblate (Hungarian)
[ ikmaak ]
* Translated using Weblate (Dutch)
* Translated using Weblate (German)
[ James Valleroy ]
* debian: Update debconf Portuguese translation (Closes: #1107447)
- Thanks to Américo Monteiro for the patch.
* performance: Handle install for trixie
* debian: Set the branch for trixie
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Mon, 23 Jun 2025 21:13:48 -0400
freedombox (25.9.1) unstable; urgency=medium
[ Sripath Roy Koganti ]
* Translated using Weblate (Telugu)
[ kosagi ]
* Translated using Weblate (Catalan)
[ Максим Горпиніч ]
* Translated using Weblate (Ukrainian)
[ James Valleroy ]
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Mon, 02 Jun 2025 20:16:21 -0400
freedombox (25.9) unstable; urgency=medium
[ klu2300030052 ]

2
debian/control vendored
View File

@ -61,7 +61,7 @@ Build-Depends:
xsltproc
Standards-Version: 4.6.2
Homepage: https://salsa.debian.org/freedombox-team/freedombox
Vcs-Git: https://salsa.debian.org/freedombox-team/freedombox.git
Vcs-Git: https://salsa.debian.org/freedombox-team/freedombox.git -b debian/trixie
Vcs-Browser: https://salsa.debian.org/freedombox-team/freedombox
Rules-Requires-Root: no

2
debian/gbp.conf vendored
View File

@ -1,5 +1,5 @@
[DEFAULT]
debian-branch = main
debian-branch = debian/trixie
[dch]
git-log = --no-merges

34
debian/po/pt.po vendored
View File

@ -1,31 +1,33 @@
# Translation of plinth debconf templates to Portuguese
# Translation of freedombox debconf messages to European Portuguese
# Copyright (C) 2019 FreedomBox packaging team <freedombox-pkg-team@lists.alioth.debian.org>
# This file is distributed under the same license as the plinth package.
# Rui Branco - DebianPT <ruipb@debianpt.org>, 2018.
# This file is distributed under the same license as the freedombox package.
#
# Rui Branco - DebianPT <ruipb@debianpt.org>, 2018.
# Américo Monteiro <a_monteiro@gmx.com>, 2025.
msgid ""
msgstr ""
"Project-Id-Version: plinth 0.37.0\n"
"Report-Msgid-Bugs-To: plinth@packages.debian.org\n"
"POT-Creation-Date: 2019-11-18 18:11-0500\n"
"PO-Revision-Date: 2018-09-27 15:33+0100\n"
"Last-Translator: Rui Branco - DebianPT <ruipb@debianpt.org>\n"
"Language-Team: Portuguese <traduz@debianpt.org>\n"
"Project-Id-Version: freedombox 25.9.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-07 15:09+0000\n"
"PO-Revision-Date: 2025-06-07 20:00+0100\n"
"Last-Translator: Américo Monteiro <a_monteiro@gmx.com>\n"
"Language-Team: Portuguese <>\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 22.12.3\n"
#. Type: note
#. Description
#: ../templates:1001
#: ../freedombox.templates:1001
msgid "FreedomBox first wizard secret - ${secret}"
msgstr "Primeiro segredo FreedomBox - ${secret}"
msgstr "Primeiro segredo de feiticeiro FreedomBox - ${secret}"
#. Type: note
#. Description
#: ../templates:1001
#, fuzzy
#: ../freedombox.templates:1001
#| msgid ""
#| "Please save this string. You will be asked to enter this in the first "
#| "screen after you launch the FreedomBox interface. In case you lose it, "
@ -35,6 +37,6 @@ msgid ""
"first screen after you launch the FreedomBox web interface. In case you lose "
"it, you can retrieve it by running the following command:"
msgstr ""
"Por favor guarde esta 'string'. Ser-lhe-á pedido para a introduzir na "
"primeira tela assim que lance a interface FreedomBox. No caso de a perder, "
"poderá encontrá-la no ficheiro /var/lib/plinth/firstboot-wizard-secret."
"Por favor anote o segredo em cima. Irá ser-lhe pedido o introduzir no "
"primeiro ecrã após lançar a interface web do FreedomBox. No caso de o "
"perder, consegue o obter ao correr o seguinte comando:"

View File

@ -0,0 +1,158 @@
#language en
##TAG:TRANSLATION-HEADER-START
~- [[FreedomBox/Guide/ExposeLocalService|English]] - [[DebianWiki/EditorGuide#translation|(+)]] -~
##TAG:TRANSLATION-HEADER-END
<<TableOfContents>>
## BEGIN_INCLUDE
== Expose a Local Service to Internet using FreedomBox ==
This guide describes to expose a local service you have on your LAN to the internet using FreedomBox that is already exposed on the internet.
=== Goal ===
* ''You have a !FreedomBox running'' with a working domain already setup. You are able to access your !FreedomBox using a URL such as `https://www.mysite.example/` .
* ''You have a different server running a local service'' on LAN that you wish to expose to the Internet on the same domain as your !FreedomBox. The local service must be a web service using the HTTP protocol (it is also possible to setup non-HTTP service, but that is a different approach). Optionally, you can have special domain assigned specifically for this local service.
* You wish for ''!FreedomBox to handle the TLS certificates'' for this domain as !FreedomBox typically does. Your local service need not setup and manage TLS certificates.
* Optionally, you may want to ''limit access to local service using !FreedomBox credentials''. Only users with a !FreedomBox account (and belonging to a chosen group) will be able to access this service. The local service will not be available to general public on the Internet. This way you can host local services that dont implement their own authentication or local services with their own authentication mechanisms disabled.
=== Exposing Local LAN servers ===
* To expose the service, create an Apache configuration file in `/etc/apache2/conf-available/` and write a `ProxyPass` directive. Assuming your local service is running on a computer with IP address `192.168.0.20` on port `3000`, you can do this by running a command (as a root user on the terminal):
{{{#!highlight bash
cat > /etc/apache2/conf-available/my-local-service.conf <<EOL
ProxyPass /myservice http://192.168.0.20:3000/
EOL
}}}
* Then, enable this Apache configuration. Run the following command:
{{{#!highlight bash
a2enconf my-local-service
}}}
* Then reload Apache web server.
{{{#!highlight bash
systemctl reload apache2
}}}
You can now access your local service at the following URL `https://www.mysite.example/myservice/` . Note that the URL is a secure URL with `https://`. The certificates will be managed by FreedomBox/Lets Encrypt. All your other apps and services work as usual. You can add any number services you want this way.
=== Running the Service on FreedomBox Itself ===
The above approach will also work if the local service is running on !FreedomBox itself. In this case, the `ProxyPass` directive in the configuration should be modified to look like `ProxyPass /myservice http://127.0.0.1:3000/`.
=== Disabling the service ===
To disable exposing the local service:
1. Disable the Apache configuration file.
{{{#!highlight bash
a2disconf my-local-service
}}}
1. Then, reload Apache web server.
{{{#!highlight bash
systemctl reload apache2
}}}
=== Adding Authentication ===
You can configure the service to be available to only users with !FreedomBox account. This is a good choice if:
* The local service that is exposed to the Internet should not be available to everyone. And,
* The local service does not provide its own authentication mechanism. Or,
* The local service provides its own authentication but you dont want to maintain a different set of user accounts for that service and want to reuse your FreedomBox user accounts.
1. Update the Apache configuration file `/etc/apache2/conf-available/my-local-service.conf` to look like the following.
{{{#!highlight apache
<Location /myservice/>
Include includes/freedombox-single-sign-on.conf
ProxyPass http://192.168.0.20:3000/
</Location>
}}}
1. Then, reload Apache web server.
{{{#!highlight bash
systemctl reload apache2
}}}
If you wish for only some groups of users to be able to access the service, another change to the configuration is needed. Make the configuration look like the following if you wish to allow users of “web-search” group and also users of “admin” group to access the local service. All other users even if they have a valid !FreedomBox account will be denied access.
{{{#!highlight apache
<Location /myservice/>
Include includes/freedombox-single-sign-on.conf
<IfModule mod_auth_pubtkt.c>
TKTAuthToken "web-search" "admin"
</IfModule>
ProxyPass http://192.168.0.20:3000/
</Location>
}}}
=== Hosting the Service on a Separate Domain ===
Some services and web applications hosted under a URL fragment such as `/myservice/` do not work well. They require an entire domain or subdomain to be dedicated to them. In these cases too, !FreedomBox can expose local services.
1. First acquire a domain or a subdomain.
* If your domain is a custom domain that you own, go to the DNS settings on your domain name provider and add a subdomain. You can create a CNAME record that simply points to the main domain.
* If you are using !FreedomBox Dynamic DNS service, then login into https://ddns.freedombox.org and enable the “Wildcard” option. With this change, for a domain (such as `example.fbx.one`), all subdomains (such as `myservice.example.fbx.one`) of your domain will point to your main domain.
1. Add the new domain into !FreedomBox. Goto System → Name Services → Domain (regular) → Add. For example, add `myservice.mysite.example`.
1. Then create an Apache configuration file at `/etc/apache2/includes/<domainname>-include.conf`. For our example this is: `/etc/apache2/includes/myservice.mysite.example-include.conf`. The contents of the file should be:
{{{#!highlight apache
ProxyPass / http://192.168.0.20:3000/
}}}
1. Modify the above file for authentication if necessary by adding the `Include` and `<IfModule>` configuration directives as shown in the authentication section above.
=== Troubleshooting ===
When your setup does not work as expected, to debug, run a temporary web service on your FreedomBox.
1. Create a temporary directory with an index.html page on the !FreedomBox.
{{{#!highlight bash
mkdir temp
cd temp
cat > index.html <<EOL
<!DOCTYPE html>
<html>
<head>
<title>My test page</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
EOL
}}}
1. Run a temporary web server (press Control-C to terminate):
{{{#!highlight bash
python3 -m http.server 3000
}}}
1. Update the Apache configuration to point to this temporary service on !FreedomBox.
{{{#!highlight apache
ProxyPass /myservice http://127.0.0.1:3000/
}}}
=== Extras ===
There are many additional features that Apache can provide to improve the local service. For these, [[https://httpd.apache.org/docs/current/|explore Apache documentation]]. Some features include:
* Serving static files such as JS, CSS, and media files from local directory without invoking the local service to improve performance.
* Caching the responses from the local service to improve performance.
* Setting additional headers for security, cache control, etc.
* Modify the HTTP header responses from the service when it does not work well to hosting under a URL fragment such as `/myservice/`.
* Perform redirects from `http://` URL to `https://` and setting HSTS header.
* Load balancing among multiple local services for high availability, scaling, etc.
* And more.
## END_INCLUDE
Back to [[FreedomBox/Features|Features introduction]] or [[FreedomBox/Manual|manual]] pages.
<<Include(FreedomBox/Portal)>>
----
CategoryFreedomBox

View File

@ -0,0 +1,55 @@
#language en
##TAG:TRANSLATION-HEADER-START
Translations ~- [[DebianWiki/EditorGuide#translation|(+)]] - [[FreedomBox/Manual/Kiwix|English]] - [[es/FreedomBox/Manual/Kiwix|Español]] -~
##TAG:TRANSLATION-HEADER-END
<<TableOfContents()>>
## BEGIN_INCLUDE
== Kiwix (Offline Wikipedia) ==
'''Available since:''' version 23.19
||<tablestyle="float: right;"> {{attachment:kiwix-tile.png|Kiwix icon}} ||
[[https://en.wikipedia.org/wiki/Kiwix|Kiwix]] can serve archives of websites offline. It was originally created to serve an offline version of Wikipedia, the free encyclopedia.
=== Use Cases ===
[[https://en.wikibooks.org/wiki/FreedomBox_for_Communities|FreedomBox for Communities]] was already using Kiwix years before it was officially included as an app. Kiwix was used to serve content over community Wi-Fi networks in [[https://en.wikipedia.org/wiki/Gangadevipalli#Free_Community_WiFi|villages]] of India with unreliable or insufficient Internet access. In addition to an offline Wikipedia, Kiwix served
* the archive "Wikipedia for Schools" which was used by school teachers and students for homework assignments and as a teaching aid.
* the archive "!WikiSource (in Telugu)" which served as a digital library.
Kiwix is also useful when you have reliable Internet access.
1. Archival and preservation: Archives of websites can be created and preserved as ZIM files. These archives can be served using Kiwix.
2. Fast access to slow websites: An offline archive can be faster to access than a website.
3. Access to websites that can be temporarily unavailable. For example, the Low Tech Magazine is hosted on a solar-powered single-board computer and could go offline sometimes. There is a Kiwix archive available for it which can be hosted locally.
=== Kiwix on FreedomBox ===
!FreedomBox serves the Debian package called kiwix-tools which allows managing and serving content archives in ZIM file format. ZIM files can be added or removed by a !FreedomBox administrator or any user in the "kiwix" user group.
Kiwix on !FreedomBox is available via web interface only. There are mobile and desktop clients for Kiwix, but they can only read local archives. They cannot pull content from Kiwix hosted on !FreedomBox.
The web interface of Kiwix is available for public access by default.
=== Finding content archives ===
To find content for Kiwix, go to [[https://library.kiwix.org|library.kiwix.org]]. You can download archives (called "books") using direct download or using BitTorrent. The website itself is a Kiwix installation, so you can have a preview of the content before downloading, to check that the archive is not broken.
An alternative source of the same files is [[https://wiki.kiwix.org/wiki/Main_Page|wiki.kiwix.org]], a wiki with download links and more information about the Kiwix project.
=== Creating content archives ===
The [[https://openzim.org/|OpenZim]] project maintains tools to create ZIM files. The tool [[https://github.com/openzim/zimit|zimit]] is a complete solution that can scrape a website and create a ZIM file. You can also request a ZIM archive using the website [[https://youzim.it|youzim.it]].
=== External links ===
* Upstream project: https://kiwix.org/
* Upstream documentation: https://kiwix.org/frequently-asked-questions/
## END_INCLUDE
Back to [[FreedomBox/Features|Features introduction]] or [[FreedomBox/Manual|manual]] pages.
<<Include(FreedomBox/Portal)>>
----
CategoryFreedomBox

View File

@ -93,7 +93,7 @@ The front page includes shortcuts to apps that have been installed and are enabl
=== Apps menu ===
The Apps menu can be accessed by clicking the grid icon, next to the !FreedomBox logo. This page lists all of the apps that are available for installing on !FreedomBox. Click the name of an app to visit its page, where you can install and configure it.
The Apps menu can be accessed by clicking the grid icon, next to the !FreedomBox logo. This page lists all of the apps that are available for installing on !FreedomBox. Click the name of an app to visit its page, where you can install and configure it. Currently installed and enabled apps are shown above the remaining available apps.
{{attachment:ui_apps.png|Apps|width=600}}

View File

@ -8,6 +8,31 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version.
== FreedomBox 25.9.4 (2025-08-02) ==
* distupgrade: Handle comments in sources.list file
* distupgrade: Update Trixie's release date as announced
== FreedomBox 25.9.3 (2025-07-21) ==
* config: Allow overriding target path in dropin config component
* email: Add support for Dovecot 2.4
* email: Start servers during re-setup if they are not running
* locale: Update translations for Albanian, Bulgarian, Catalan, Estonian, Tamil
* sogo: Fix typo in configuration for sieve server
== FreedomBox 25.9.2 (2025-06-23) ==
* debian: Set the branch for trixie
* debian: Update debconf Portuguese translation
* locale: Add new translation for Estonian
* locale: Update translations for Dutch, German, Hungarian
* performance: Handle install for trixie
== FreedomBox 25.9.1 (2025-06-02) ==
* locale: Update translations for Catalan, Telugu, Ukrainian
== FreedomBox 25.9 (2025-05-05) ==
* locale: Add translation for Catalan

View File

@ -28,6 +28,7 @@
<<Include(FreedomBox/Manual/Infinoted, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Janus, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/JSXC, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Kiwix, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/MatrixSynapse, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/MediaWiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Minetest, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
@ -80,6 +81,9 @@
<<Include(FreedomBox/Manual/Upgrades, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Guides =
<<Include(FreedomBox/Guide/ExposeLocalService, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Hardware =
<<Include(FreedomBox/Hardware, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Hardware/PioneerEdition, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 292 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -28,6 +28,7 @@
<<Include(FreedomBox/Manual/Infinoted, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Janus, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/JSXC, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Kiwix, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/MatrixSynapse, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/MediaWiki, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Minetest, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
@ -80,6 +81,9 @@
<<Include(FreedomBox/Manual/Upgrades, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Manual/Users, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Guides =
<<Include(FreedomBox/Guide/ExposeLocalService, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
= Hardware =
<<Include(FreedomBox/Hardware, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>
<<Include(FreedomBox/Hardware/PioneerEdition, , from="## BEGIN_INCLUDE", to="## END_INCLUDE")>>

View File

@ -8,6 +8,31 @@ For more technical details, see the [[https://salsa.debian.org/freedombox-team/f
The following are the release notes for each !FreedomBox version.
== FreedomBox 25.9.4 (2025-08-02) ==
* distupgrade: Handle comments in sources.list file
* distupgrade: Update Trixie's release date as announced
== FreedomBox 25.9.3 (2025-07-21) ==
* config: Allow overriding target path in dropin config component
* email: Add support for Dovecot 2.4
* email: Start servers during re-setup if they are not running
* locale: Update translations for Albanian, Bulgarian, Catalan, Estonian, Tamil
* sogo: Fix typo in configuration for sieve server
== FreedomBox 25.9.2 (2025-06-23) ==
* debian: Set the branch for trixie
* debian: Update debconf Portuguese translation
* locale: Add new translation for Estonian
* locale: Update translations for Dutch, German, Hungarian
* performance: Handle install for trixie
== FreedomBox 25.9.1 (2025-06-02) ==
* locale: Update translations for Catalan, Telugu, Ukrainian
== FreedomBox 25.9 (2025-05-05) ==
* locale: Add translation for Catalan

View File

@ -3,4 +3,4 @@
Package init file.
"""
__version__ = '25.9'
__version__ = '25.9.3'

View File

@ -108,14 +108,12 @@ class DropinConfigs(app_module.FollowerComponent):
return results
@staticmethod
def get_target_path(path):
def get_target_path(self, path):
"""Return Path object for a target path."""
target = pathlib.Path(DropinConfigs.ROOT)
target /= DropinConfigs.DROPIN_CONFIG_ROOT.lstrip('/')
target = pathlib.Path(self.ROOT)
target /= self.DROPIN_CONFIG_ROOT.lstrip('/')
return target / path.lstrip('/')
@staticmethod
def get_etc_path(path):
def get_etc_path(self, path):
"""Return Path object for etc path."""
return pathlib.Path(DropinConfigs.ROOT) / path.lstrip('/')
return pathlib.Path(self.ROOT) / path.lstrip('/')

View File

@ -94,7 +94,6 @@ def dump_database(backup_file: str | pathlib.Path, database_name: str):
file if it exists.
"""
backup_path = pathlib.Path(backup_file)
backup_path.parent.mkdir(parents=True, exist_ok=True)
with action_utils.service_ensure_running('postgresql'):
with open(backup_path, 'w', encoding='utf-8') as file_handle:
_run_as([

View File

@ -8,9 +8,9 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2025-02-25 21:04+0000\n"
"Last-Translator: 109247019824 <109247019824@users.noreply.hosted.weblate."
"org>\n"
"PO-Revision-Date: 2025-07-20 18:01+0000\n"
"Last-Translator: 109247019824 <109247019824@users.noreply.hosted.weblate.org>"
"\n"
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/bg/>\n"
"Language: bg\n"
@ -18,7 +18,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 5.10.2-dev\n"
"X-Generator: Weblate 5.13-dev\n"
#: config.py:103
#, python-brace-format
@ -199,7 +199,7 @@ msgstr "Домейн в местната мрежа"
#: modules/avahi/manifest.py:14
msgid "Auto-discovery"
msgstr ""
msgstr "Автоматично откриване"
#: modules/avahi/manifest.py:14 modules/backups/manifest.py:17
msgid "Local"
@ -207,7 +207,7 @@ msgstr "Местно"
#: modules/avahi/manifest.py:14
msgid "mDNS"
msgstr ""
msgstr "mDNS"
#: modules/backups/__init__.py:24
msgid "Backups allows creating and managing backup archives."
@ -8203,10 +8203,8 @@ msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:9
#: modules/upgrades/templates/upgrades-dist-upgrade.html:11
#: modules/upgrades/templates/upgrades_configure.html:16
#, fuzzy
#| msgid "Distribution update started"
msgid "Distribution Update"
msgstr "Започнато е обновяване на дистрибуцията"
msgstr "Начало на бновяване на дистрибуцията"
#: modules/upgrades/__init__.py:396
msgid "Check for package holds"
@ -8267,10 +8265,8 @@ msgid "Next"
msgstr "Напред"
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:11
#, fuzzy
#| msgid "Could not start distribution update"
msgid "Confirm Distribution Update?"
msgstr "Обновяването на дистрибуцията не може да бъде стартирано"
msgstr "Потвърждавате ли бновяване на дистрибуцията?"
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:21
#, python-format
@ -8303,10 +8299,8 @@ msgid "If the process is interrupted, you should be able to continue it."
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:66
#, fuzzy
#| msgid "Could not start distribution update"
msgid "Confirm & Start Distribution Update"
msgstr "Обновяването на дистрибуцията не може да бъде стартирано"
msgstr "Потвърждаване и обновяване на дистрибуцията"
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:15
msgid ""
@ -8336,10 +8330,8 @@ msgid ""
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:42
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Go to Distribution Update"
msgstr "Надграждане на дистрибуцията до тестова"
msgstr "Към обновяване на дистрибуцията"
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:46
#: modules/upgrades/templates/upgrades-new-release.html:22
@ -8368,16 +8360,12 @@ msgid ""
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:50
#, fuzzy
#| msgid "Frequent feature updates are activated."
msgid "Automatic updates are disabled."
msgstr "Честото обновяване на пакети е включено."
msgstr "Автоматичното обновяване е изключено."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:54
#, fuzzy
#| msgid "Distribution update started"
msgid "Distribution upgrades are disabled."
msgstr "Започнато е обновяване на дистрибуцията"
msgstr "Обновяванията на дистрибуцията са изключени."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:58
msgid ""
@ -8390,10 +8378,8 @@ msgid "Your current distribution is mixed or not understood."
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:72
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Current Distribution:"
msgstr "Надграждане на дистрибуцията до тестова"
msgstr "Текуща дистрибуция:"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:74
msgid "Unknown or mixed"
@ -8409,10 +8395,8 @@ msgid "Released: %(date)s."
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:91
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Next Stable Distribution:"
msgstr "Надграждане на дистрибуцията до тестова"
msgstr "Следваща стабилна дистрибуция:"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:93
msgid "Unknown"
@ -8467,22 +8451,16 @@ msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:157
#: modules/upgrades/templates/upgrades-dist-upgrade.html:172
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Start Distribution Update"
msgstr "Надграждане на дистрибуцията до тестова"
msgstr "Начало на обновяване на дистрибуцията"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:162
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Continue Distribution Update"
msgstr "Надграждане на дистрибуцията до тестова"
msgstr "Продължаване обновяването на дистрибуцията"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:167
#, fuzzy
#| msgid "Starting distribution upgrade test."
msgid "Start Distribution Update (for testing)"
msgstr "Начало на опит за обновяване на дистрибуцията."
msgstr "Начало на обновяване на дистрибуцията (за проба)"
#: modules/upgrades/templates/upgrades-new-release.html:9
#, python-format
@ -8562,10 +8540,8 @@ msgid "Error when configuring unattended-upgrades"
msgstr "Грешка при настройка на unattended-upgrades"
#: modules/upgrades/views.py:117
#, fuzzy
#| msgid "Starting distribution upgrade test."
msgid "Started distribution update."
msgstr "Начало на опит за обновяване на дистрибуцията."
msgstr "Обновяване на дистрибуцията е започнато."
#: modules/upgrades/views.py:153
msgid "Upgrade process started."

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2025-05-29 10:01+0000\n"
"PO-Revision-Date: 2025-06-25 22:04+0000\n"
"Last-Translator: kosagi <marti.torra@natana.cat>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/freedombox/"
"freedombox/ca/>\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 5.12-dev\n"
"X-Generator: Weblate 5.13-dev\n"
#: config.py:103
#, python-brace-format
@ -2599,26 +2599,28 @@ msgid ""
"Wiki title and description can be set from within the wiki. This file name "
"is independent of the wiki title."
msgstr ""
"El títol i la descripció del wiki es poden establir des de dins del wiki. "
"Aquest nom de fitxer és independent del títol del wiki."
#: modules/featherwiki/forms.py:23 modules/tiddlywiki/forms.py:23
msgid "New name for the wiki file, with file extension \".html\""
msgstr ""
msgstr "Nou nom per al fitxer del wiki, amb l'extensió de fitxer \".html\""
#: modules/featherwiki/forms.py:25 modules/tiddlywiki/forms.py:25
msgid "Renaming the file has no effect on the title of the wiki."
msgstr ""
msgstr "Canviar el nom del fitxer no té cap efecte sobre el títol del wiki."
#: modules/featherwiki/forms.py:32
msgid "A Feather Wiki file with .html file extension"
msgstr ""
msgstr "Un fitxer Feather Wiki amb l'extensió de fitxer .html"
#: modules/featherwiki/forms.py:35
msgid "Feather Wiki files must be in HTML format"
msgstr ""
msgstr "Els fitxers Feather Wiki han d'estar en format HTML"
#: modules/featherwiki/forms.py:37
msgid "Upload an existing Feather Wiki file from this computer."
msgstr ""
msgstr "Carrega un fitxer Feather Wiki existent des d'aquest ordinador."
#: modules/featherwiki/manifest.py:18
#: modules/help/templates/help_about.html:108 modules/ikiwiki/manifest.py:15
@ -2629,7 +2631,7 @@ msgstr "Wiki"
#: modules/featherwiki/manifest.py:18 modules/infinoted/manifest.py:46
#: modules/tiddlywiki/manifest.py:20
msgid "Note taking"
msgstr ""
msgstr "Prendre notes"
#: modules/featherwiki/manifest.py:18 modules/ikiwiki/manifest.py:15
#: modules/mediawiki/manifest.py:25 modules/tiddlywiki/manifest.py:21
@ -2639,17 +2641,17 @@ msgstr "Pàgina Web"
#: modules/featherwiki/manifest.py:18 modules/tiddlywiki/manifest.py:25
msgid "Quine"
msgstr ""
msgstr "Quine"
#: modules/featherwiki/manifest.py:18 modules/nextcloud/manifest.py:56
#: modules/tiddlywiki/manifest.py:26
msgid "Non-Debian"
msgstr ""
msgstr "No-Debian"
#: modules/featherwiki/templates/featherwiki_configure.html:12
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:12
msgid "Manage Wikis"
msgstr ""
msgstr "Gestiona les Wikis"
#: modules/featherwiki/templates/featherwiki_configure.html:16
#: modules/featherwiki/templates/featherwiki_configure.html:18
@ -2658,100 +2660,102 @@ msgstr ""
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:18
#: modules/tiddlywiki/views.py:47
msgid "Create Wiki"
msgstr ""
msgstr "Crea una Wiki"
#: modules/featherwiki/templates/featherwiki_configure.html:21
#: modules/featherwiki/templates/featherwiki_configure.html:23
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:21
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:23
msgid "Upload Wiki"
msgstr ""
msgstr "Penja una Wiki"
#: modules/featherwiki/templates/featherwiki_configure.html:30
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:30
msgid "No wikis available."
msgstr ""
msgstr "No hi ha wikis disponibles."
#: modules/featherwiki/templates/featherwiki_configure.html:36
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:36
#, python-format
msgid "Go to wiki %(wiki)s"
msgstr ""
msgstr "Ves a la wiki %(wiki)s"
#: modules/featherwiki/templates/featherwiki_configure.html:43
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:43
#, python-format
msgid "Rename wiki %(wiki)s"
msgstr ""
msgstr "Reanomena la wiki %(wiki)s"
#: modules/featherwiki/templates/featherwiki_configure.html:50
#: modules/tiddlywiki/templates/tiddlywiki_configure.html:50
#, python-format
msgid "Delete wiki %(wiki)s"
msgstr ""
msgstr "Elimina la wiki %(wiki)s"
#: modules/featherwiki/templates/featherwiki_delete.html:12
#: modules/tiddlywiki/templates/tiddlywiki_delete.html:12
#, python-format
msgid "Delete wiki <em>%(name)s</em>"
msgstr ""
msgstr "Elimina la wiki <em>%(name)s</em>"
#: modules/featherwiki/templates/featherwiki_delete.html:18
msgid ""
"<strong>Hint</strong>: You can download a copy of this wiki from within "
"Feather Wiki before deleting it."
msgstr ""
"<strong>Consell</strong>: Pots descarregar una còpia d'aquest wiki des de "
"dins de Feather Wiki abans d'eliminar-lo."
#: modules/featherwiki/templates/featherwiki_delete.html:25
#: modules/tiddlywiki/templates/tiddlywiki_delete.html:25
msgid "Delete this wiki file permanently?"
msgstr ""
msgstr "Eliminar aquest fitxer de wiki de manera permanent?"
#: modules/featherwiki/templates/featherwiki_upload_file.html:20
#: modules/tiddlywiki/templates/tiddlywiki_upload_file.html:20
msgid "Upload"
msgstr ""
msgstr "Penja"
#: modules/featherwiki/views.py:20 modules/tiddlywiki/views.py:20
msgid "A wiki file with the given name already exists."
msgstr ""
msgstr "Ja hi ha un fitxer de wiki amb aquest nom."
#: modules/featherwiki/views.py:54 modules/tiddlywiki/views.py:54
msgid "Wiki created."
msgstr ""
msgstr "Wiki creada."
#: modules/featherwiki/views.py:59 modules/tiddlywiki/views.py:59
msgid "An error occurred while creating the wiki."
msgstr ""
msgstr "Hi ha hagut un error al crear la wiki."
#: modules/featherwiki/views.py:76 modules/tiddlywiki/views.py:76
msgid "Rename Wiki"
msgstr ""
msgstr "Reanomena la Wiki"
#: modules/featherwiki/views.py:84 modules/tiddlywiki/views.py:84
msgid "Wiki renamed."
msgstr ""
msgstr "Nom de la wiki actualitzat."
#: modules/featherwiki/views.py:89 modules/tiddlywiki/views.py:89
msgid "An error occurred while renaming the wiki."
msgstr ""
msgstr "Hi ha hagut un error al reanomenar la wiki."
#: modules/featherwiki/views.py:106 modules/tiddlywiki/views.py:106
msgid "Upload Wiki File"
msgstr ""
msgstr "Penja un fitxer de Wiki"
#: modules/featherwiki/views.py:115 modules/tiddlywiki/views.py:116
msgid "Wiki file added."
msgstr ""
msgstr "Fitxer de Wiki afegit."
#: modules/featherwiki/views.py:119 modules/tiddlywiki/views.py:120
msgid "Failed to add wiki file."
msgstr ""
msgstr "No s'ha pogut afegir el fitxer de wiki."
#: modules/featherwiki/views.py:138 modules/tiddlywiki/views.py:139
#, python-brace-format
msgid "Could not delete {name}"
msgstr ""
msgstr "No s'ha pogut eliminar {name}"
#: modules/firewall/__init__.py:25
#, python-brace-format
@ -2760,83 +2764,87 @@ msgid ""
"network traffic on your {box_name}. Keeping a firewall enabled and properly "
"configured reduces risk of security threat from the Internet."
msgstr ""
"El tallafocs és un sistema de seguretat que controla el trànsit de xarxa "
"entrant i sortint del teu {box_name}. Mantenir el tallafocs activat i "
"configurat correctament redueix el risc damenaces de seguretat des "
"dInternet."
#: modules/firewall/__init__.py:61
msgid "Firewall"
msgstr ""
msgstr "Tallafocs"
#: modules/firewall/__init__.py:262
msgid "Default zone is external"
msgstr ""
msgstr "La zona per defecte és externa"
#: modules/firewall/__init__.py:272
msgid "Firewall backend is nftables"
msgstr ""
msgstr "El backend del tallafocs és nftables"
#: modules/firewall/__init__.py:286
msgid "Direct passthrough rules exist"
msgstr ""
msgstr "Existeixen regles de pas directe"
#: modules/firewall/components.py:139
#, python-brace-format
msgid "Port {name} ({details}) available for internal networks"
msgstr ""
msgstr "Port {name} ({details}) disponible per a xarxes internes"
#: modules/firewall/components.py:154
#, python-brace-format
msgid "Port {name} ({details}) available for external networks"
msgstr ""
msgstr "Port {name} ({details}) disponible per a xarxes externes"
#: modules/firewall/components.py:160
#, python-brace-format
msgid "Port {name} ({details}) unavailable for external networks"
msgstr ""
msgstr "Port {name} ({details}) no disponible per a xarxes externes"
#: modules/firewall/manifest.py:10 modules/tor/templates/tor.html:25
msgid "Ports"
msgstr ""
msgstr "Ports"
#: modules/firewall/manifest.py:10
msgid "Blocking"
msgstr ""
msgstr "Bloquejant"
#: modules/firewall/manifest.py:10 modules/networks/forms.py:319
#: modules/upgrades/manifest.py:10
msgid "Automatic"
msgstr ""
msgstr "Automàtic"
#: modules/firewall/templates/firewall.html:21
msgid "Service/Port"
msgstr ""
msgstr "Servei/Port"
#: modules/firewall/templates/firewall.html:40
#: modules/letsencrypt/templates/letsencrypt.html:69
#: modules/snapshot/forms.py:23 modules/snapshot/forms.py:29
msgid "Enabled"
msgstr ""
msgstr "Habilitat"
#: modules/firewall/templates/firewall.html:43
#: modules/letsencrypt/templates/letsencrypt.html:71
#: modules/snapshot/forms.py:23 modules/snapshot/forms.py:29
#: templates/cards.html:38
msgid "Disabled"
msgstr ""
msgstr "Inhabilitat"
#: modules/firewall/templates/firewall.html:58
msgid "Permitted"
msgstr ""
msgstr "Permès"
#: modules/firewall/templates/firewall.html:61
msgid "Permitted (internal only)"
msgstr ""
msgstr "Permès (només intern)"
#: modules/firewall/templates/firewall.html:64
msgid "Permitted (external only)"
msgstr ""
msgstr "Permès (només extern)"
#: modules/firewall/templates/firewall.html:67
msgid "Blocked"
msgstr ""
msgstr "Bloquejat"
#: modules/firewall/templates/firewall.html:80
msgid ""
@ -2844,22 +2852,28 @@ msgid ""
"also permitted in the firewall and when you disable a service it is also "
"disabled in the firewall."
msgstr ""
"L'operació del tallafocs és automàtica. Quan actives un servei, també està "
"permès al tallafocs, i quan desactives un servei, també es desactiva al "
"tallafocs."
#: modules/firewall/templates/firewall.html:88
#: modules/networks/templates/networks_configuration.html:22
#: modules/storage/templates/storage.html:93
msgid "Advanced"
msgstr ""
msgstr "Avançat"
#: modules/firewall/templates/firewall.html:90
msgid ""
"Advanced firewall operations such as opening custom ports are provided by "
"the <a href=\"/_cockpit/network/firewall\">Cockpit</a> app."
msgstr ""
"Les operacions avançades del tallafocs, com ara obrir ports personalitzats, "
"les proporciona l'aplicació <a href=\"/_cockpit/network/firewall\""
">Cockpit</a>."
#: modules/first_boot/__init__.py:61
msgid "Setup complete! Next steps:"
msgstr ""
msgstr "Configuració completada! Properes passes:"
#: modules/first_boot/__init__.py:63
#, python-brace-format
@ -2867,14 +2881,16 @@ msgid ""
"Initial setup has been completed. Perform the next steps to make your "
"{box_name} operational."
msgstr ""
"La configuració inicial sha completat. Realitza els següents passos per fer "
"que el teu {box_name} estigui operatiu."
#: modules/first_boot/__init__.py:66
msgid "Next steps"
msgstr ""
msgstr "Propers passos"
#: modules/first_boot/__init__.py:73
msgid "See next steps"
msgstr ""
msgstr "Veure els passos següents"
#: modules/first_boot/forms.py:14
#, python-brace-format
@ -2883,14 +2899,17 @@ msgid ""
"also be obtained by running the command \"sudo cat /var/lib/plinth/firstboot-"
"wizard-secret\" on your {box_name}"
msgstr ""
"Introdueix el secret generat durant la instal·lació de FreedomBox. Aquest "
"secret també es pot obtenir executant la comanda "
"\"sudo cat /var/lib/plinth/firstboot-wizard-secret\" al teu {box_name}"
#: modules/first_boot/forms.py:19
msgid "Firstboot Wizard Secret"
msgstr ""
msgstr "Secret de l'Assistent de Primera Execució"
#: modules/first_boot/templates/firstboot_complete.html:14
msgid "Setup Complete! Next Steps:"
msgstr ""
msgstr "Configuració completada! Passos següents:"
#: modules/first_boot/templates/firstboot_complete.html:21
#, python-format
@ -2898,17 +2917,22 @@ msgid ""
"Automatic <a href=\"%(upgrades_url)s\" target=\"_blank\">software update</a> "
"runs daily by default. For the first time, manually run it now."
msgstr ""
"L<a href=\"%(upgrades_url)s\" target=\"_blank\">actualització automàtica de "
"programari</a> sexecuta diàriament per defecte. Per primera vegada, executa-"
"la manualment ara."
#: modules/first_boot/templates/firstboot_complete.html:30
#: modules/upgrades/templates/upgrades_configure.html:119
msgid "Update now"
msgstr ""
msgstr "Actualitza-ho ara"
#: modules/first_boot/templates/firstboot_complete.html:39
#, python-format
msgid ""
"Review <a href=\"%(privacy_url)s\" target=\"_blank\">privacy options</a>."
msgstr ""
"Revisa les <a href=\"%(privacy_url)s\" target=\"_blank\">opcions de "
"privadesa</a>."
#: modules/first_boot/templates/firstboot_complete.html:49
#, python-format
@ -2916,12 +2940,16 @@ msgid ""
"Review and setup <a href=\"%(networks_url)s\" target=\"_blank\">network "
"connections</a>. Change the default Wi-Fi password, if applicable."
msgstr ""
"Revisa i configura les <a href=\"%(networks_url)s\" target=\"_blank\""
">connexions de xarxa</a>. Canvia la contrasenya Wi-Fi per defecte, si "
"sescau."
#: modules/first_boot/templates/firstboot_complete.html:60
#, python-format
msgid ""
"Configure a <a href=\"%(names_url)s\" target=\"_blank\">domain name</a>."
msgstr ""
"Configura un <a href=\"%(names_url)s\" target=\"_blank\">nom de domini</a>."
#: modules/first_boot/templates/firstboot_complete.html:70
#, python-format
@ -2929,6 +2957,8 @@ msgid ""
"Configure and schedule remote <a href=\"%(backups_url)s\" "
"target=\"_blank\">backups</a>."
msgstr ""
"Configura i programa còpies de seguretat <a href=\"%(backups_url)s\" target="
"\"_blank\">remotes</a>."
#: modules/first_boot/templates/firstboot_complete.html:81
#, python-format
@ -2936,14 +2966,16 @@ msgid ""
"Put %(box_name)s to use by installing <a href=\"%(apps_url)s\" "
"target=\"_blank\">apps</a>."
msgstr ""
"Posa %(box_name)s en funcionament instal·lant <a href=\"%(apps_url)s\" "
"target=\"_blank\">aplicacions</a>."
#: modules/first_boot/templates/firstboot_welcome.html:29
msgid "Start Setup"
msgstr ""
msgstr "Inicia la configuració"
#: modules/first_boot/views.py:41
msgid "Setup Complete"
msgstr ""
msgstr "Configuració completada"
#: modules/gitweb/__init__.py:22
msgid ""
@ -2955,16 +2987,25 @@ msgid ""
"available graphical clients. And you can share your code with people around "
"the world."
msgstr ""
"Git és un sistema de control de versions distribuït per fer el seguiment de "
"canvis en el codi font durant el desenvolupament de programari. Gitweb "
"proporciona una interfície web als repositoris Git. Pots navegar per "
"l'historial i el contingut del codi font, utilitzar la cerca per trobar "
"commits i codi rellevants. També pots clonar repositoris i pujar canvis de "
"codi amb un client Git de línia de comandes o amb diversos clients gràfics "
"disponibles. I pots compartir el teu codi amb persones de tot el món."
#: modules/gitweb/__init__.py:29
msgid ""
"To learn more on how to use Git visit <a href=\"https://git-scm.com/docs/"
"gittutorial\">Git tutorial</a>."
msgstr ""
"Per aprendre més sobre com utilitzar Git, visita <a href="
"\"https://git-scm.com/docs/gittutorial\">tutorial de Git</a>."
#: modules/gitweb/__init__.py:45
msgid "Read-write access to Git repositories"
msgstr ""
msgstr "Accés de lectura i escriptura als repositoris Git"
#: modules/gitweb/__init__.py:48 modules/gitweb/manifest.py:10
msgid "Gitweb"
@ -2972,128 +3013,130 @@ msgstr "Gitweb"
#: modules/gitweb/forms.py:59
msgid "Invalid repository URL."
msgstr ""
msgstr "URL del repositori no vàlida."
#: modules/gitweb/forms.py:69
msgid "Invalid repository name."
msgstr ""
msgstr "Nom del repositori no vàlid."
#: modules/gitweb/forms.py:77
msgid "Name of a new repository or URL to import an existing repository."
msgstr ""
msgstr "Nom dun repositori nou o URL per importar un repositori existent."
#: modules/gitweb/forms.py:83
msgid "Description of the repository"
msgstr ""
msgstr "Descripció del repositori"
#: modules/gitweb/forms.py:84 modules/gitweb/forms.py:88
msgid "Optional, for displaying on Gitweb."
msgstr ""
msgstr "Opcional, per mostrar a Gitweb."
#: modules/gitweb/forms.py:86
msgid "Repository's owner name"
msgstr ""
msgstr "Nom del propietari del Repositori"
#: modules/gitweb/forms.py:91
msgid "Private repository"
msgstr ""
msgstr "Repositori privat"
#: modules/gitweb/forms.py:92
msgid "Allow only authorized users to access this repository."
msgstr ""
msgstr "Permet que només usuaris autoritzats accedeixin a aquest repositori."
#: modules/gitweb/forms.py:113 modules/gitweb/forms.py:155
msgid "A repository with this name already exists."
msgstr ""
msgstr "Ja existeix un repositori amb aquest nom."
#: modules/gitweb/forms.py:126
msgid "Name of the repository"
msgstr ""
msgstr "Nom del repositori"
#: modules/gitweb/forms.py:130
msgid "An alpha-numeric string that uniquely identifies a repository."
msgstr ""
msgstr "Una cadena alfanumèrica que identifica de manera única un repositori."
#: modules/gitweb/forms.py:134
msgid "Default branch"
msgstr ""
msgstr "Branca principal"
#: modules/gitweb/forms.py:135
msgid "Gitweb displays this as a default branch."
msgstr ""
msgstr "La Gitweb sempre mostra això com a branca principal."
#: modules/gitweb/manifest.py:18
msgid "Git"
msgstr ""
msgstr "Git"
#: modules/gitweb/manifest.py:37
msgid "Git hosting"
msgstr ""
msgstr "Allotjament Git"
#: modules/gitweb/manifest.py:37
msgid "Version control"
msgstr ""
msgstr "Control de versions"
#: modules/gitweb/manifest.py:37
msgid "Developer tool"
msgstr ""
msgstr "Eines de desenvolupador"
#: modules/gitweb/templates/gitweb_configure.html:13
msgid "Manage Repositories"
msgstr ""
msgstr "Gestiona Repositoris"
#: modules/gitweb/templates/gitweb_configure.html:17
#: modules/gitweb/templates/gitweb_configure.html:19
msgid "Create repository"
msgstr ""
msgstr "Crea un repositori"
#: modules/gitweb/templates/gitweb_configure.html:26
msgid "No repositories available."
msgstr ""
msgstr "No hi ha repositoris disponibles."
#: modules/gitweb/templates/gitweb_configure.html:35
#, python-format
msgid "Go to repository %(repo.name)s"
msgstr ""
msgstr "Ves al repositori %(repo.name)s"
#: modules/gitweb/templates/gitweb_configure.html:42
msgid "Cloning…"
msgstr ""
msgstr "Clonant…"
#: modules/gitweb/templates/gitweb_configure.html:59
#, python-format
msgid "Delete repository %(repo.name)s"
msgstr ""
msgstr "Elimina el repositori %(repo.name)s"
#: modules/gitweb/templates/gitweb_delete.html:12
#, python-format
msgid "Delete Git Repository <em>%(name)s</em>"
msgstr ""
msgstr "Elimina el repositori Git <em>%(name)s</em>"
#: modules/gitweb/templates/gitweb_delete.html:18
msgid "Delete this repository permanently?"
msgstr ""
msgstr "Vols eliminar aquest repositori permanentment?"
#: modules/gitweb/views.py:46
msgid "Repository created."
msgstr ""
msgstr "Repositori creat."
#: modules/gitweb/views.py:69
msgid "An error occurred while creating the repository."
msgstr ""
msgstr "Hi ha hagut un error al crear el repositori."
#: modules/gitweb/views.py:84
msgid "Repository edited."
msgstr ""
msgstr "Repositori editat."
#: modules/gitweb/views.py:89
msgid "Edit repository"
msgstr ""
msgstr "Edita el repositori"
#: modules/gnome/__init__.py:18
msgid ""
"GNOME is a desktop environment that focuses on simplicity and ease of use."
msgstr ""
"GNOME és un entorn d'escriptori que se centra en la simplicitat i la "
"facilitat d'ús."
#: modules/gnome/__init__.py:21
#, python-brace-format
@ -3103,12 +3146,20 @@ msgid ""
"suite, and other basic utilities are available. You may install further "
"graphical applications using the software center provided within."
msgstr ""
"Aquesta aplicació transforma el teu {box_name} en un ordinador descriptori "
"si hi connectes físicament un monitor, un teclat i un ratolí. Tens "
"disponible un navegador, una suite dofimàtica i altres utilitats bàsiques. "
"També pots instal·lar més aplicacions gràfiques mitjançant el centre de "
"programari que sofereix a linterior."
#: modules/gnome/__init__.py:26
msgid ""
"This app is not suitable for low-end hardware. It requires at least 4GiB of "
"RAM, 4GiB of disk space and a GPU capable of basic 3D acceleration."
msgstr ""
"Aquesta aplicació no és adequada per a maquinari de baix rendiment. "
"Requereix com a mínim 4 GiB de RAM, 4 GiB d'espai al disc i una GPU capaç "
"d'acceleració 3D bàsica."
#: modules/gnome/__init__.py:30
#, python-brace-format
@ -3117,45 +3168,48 @@ msgid ""
"need to <a href=\"{power_url}\">restart</a> the machine for changes to take "
"effect."
msgstr ""
"Després dinstal·lar, activar, desactivar o desinstal·lar laplicació, "
"hauràs de <a href=\"{power_url}\">reiniciar</a> la màquina perquè els canvis "
"tinguin efecte."
#: modules/gnome/__init__.py:48
msgid "GNOME"
msgstr ""
msgstr "GNOME"
#: modules/gnome/manifest.py:9 templates/clients.html:42
msgid "Desktop"
msgstr ""
msgstr "Escriptori"
#: modules/gnome/manifest.py:10
msgid "Browser"
msgstr ""
msgstr "Navegador"
#: modules/gnome/manifest.py:11
msgid "Office suite"
msgstr ""
msgstr "Suite dofimàtica"
#: modules/gnome/manifest.py:12
msgid "Software store"
msgstr ""
msgstr "Botiga d'aplicacions"
#: modules/gnome/manifest.py:13
msgid "GUI"
msgstr ""
msgstr "Interfície Gràfica d'Usuari"
#: modules/gnome/manifest.py:14
msgid "Graphical apps"
msgstr ""
msgstr "Aplicacions gràfiques"
#: modules/help/__init__.py:33 modules/help/templates/help_index.html:14
#: templates/help-menu.html:8 templates/help-menu.html:14
msgid "Help"
msgstr ""
msgstr "Ajuda"
#: modules/help/__init__.py:37 modules/help/templates/help_about.html:104
#: templates/help-menu.html:20 templates/help-menu.html:21
msgctxt "User guide"
msgid "Manual"
msgstr ""
msgstr "Manual"
#: modules/help/__init__.py:41 modules/help/templates/help_support.html:9
#: modules/help/views.py:93 templates/help-menu.html:27
@ -3167,7 +3221,7 @@ msgstr "Rep Suport"
#: modules/help/views.py:87 templates/help-menu.html:33
#: templates/help-menu.html:34
msgid "Submit Feedback"
msgstr ""
msgstr "Enviar comentaris"
#: modules/help/__init__.py:49 modules/help/templates/help_about.html:113
#: modules/help/templates/help_contribute.html:9 modules/help/views.py:76
@ -3183,13 +3237,13 @@ msgstr "Sobre"
#: modules/help/templates/help_about.html:25 templates/messages.html:23
msgid "Success:"
msgstr ""
msgstr "Reeixit:"
#: modules/help/templates/help_about.html:29
#: modules/upgrades/templates/upgrades_configure.html:31
#, python-format
msgid "You are running %(os_release)s and %(box_name)s version %(version)s."
msgstr ""
msgstr "Estàs executant %(os_release)s i la versió %(version)s de %(box_name)s."
#: modules/help/templates/help_about.html:35
#, python-format
@ -3197,12 +3251,14 @@ msgid ""
"There is a new %(box_name)s version <a href=\"%(upgrades_url)s\">available</"
"a>."
msgstr ""
"Hi ha una nova versió de %(box_name)s <a href=\"%(upgrades_url)s\""
">disponible</a>."
#: modules/help/templates/help_about.html:40
#: modules/upgrades/templates/upgrades_configure.html:42
#, python-format
msgid "%(box_name)s is up to date."
msgstr ""
msgstr "%(box_name)s està actualitzat."
#: modules/help/templates/help_about.html:49
#, python-format
@ -3215,6 +3271,14 @@ msgid ""
"and a Tor relay, on a device that can replace your Wi-Fi router, so that "
"your data stays with you."
msgstr ""
"%(box_name)s és un projecte comunitari per desenvolupar, dissenyar i "
"promoure servidors personals que executen programari lliure per a "
"comunicacions privades i personals. És un dispositiu de xarxa dissenyat "
"per permetre la interacció amb la resta dInternet sota condicions de "
"privadesa i seguretat de dades protegides. Allotja aplicacions com bloc, "
"wiki, lloc web, xarxa social, correu electrònic, proxy web i un relé Tor, en "
"un dispositiu que pot substituir el teu router Wi-Fi, perquè les teves dades "
"es quedin amb tu."
#: modules/help/templates/help_about.html:62
msgid ""
@ -3225,6 +3289,12 @@ msgid ""
"giving back power to the users over their networks and machines, we are "
"returning the Internet to its intended peer-to-peer architecture."
msgstr ""
"Vivim en un món on lús que fem de la xarxa està mediatitzat per aquells que "
"sovint vetllen pels nostres interessos. Construint programari que no "
"depengui dun servei central, podem recuperar el control i la privadesa. "
"Guardant les nostres dades a casa, obtenim proteccions legals útils sobre "
"elles. Tornant el poder als usuaris sobre les seves xarxes i màquines, "
"estem retornant Internet a la seva arquitectura peer-to-peer prevista."
#: modules/help/templates/help_about.html:75
#, python-format
@ -3233,6 +3303,9 @@ msgid ""
"services; %(box_name)s aims to bring them all together in a convenient "
"package."
msgstr ""
"Hi ha diversos projectes que treballen per fer realitat un futur de serveis "
"distribuïts; %(box_name)s té com a objectiu reunir-los tots en un paquet "
"còmode."
#: modules/help/templates/help_about.html:83
#, python-format
@ -3244,6 +3317,13 @@ msgid ""
"href=\"https://sources.debian.org/\">Debian Sources</a> site, or by running "
"\"apt source <i>package_name</i>\" in a terminal (using Cockpit or SSH)."
msgstr ""
"%(box_name)s és programari lliure, llicenciat sota la GNU Affero General "
"Public License. El codi font està disponible en línia al <a href="
"\"https://salsa.debian.org/freedombox-team/freedombox\">repositori de "
"%(box_name)s</a>. A més, el codi font de qualsevol paquet Debian es pot "
"obtenir des del lloc <a href=\"https://sources.debian.org/\">Debian Sources</"
"a>, o executant \"apt source <i>nom\\_paquet</i>\" en un terminal ("
"utilitzant Cockpit o SSH)."
#: modules/help/templates/help_about.html:97
msgid "Learn"
@ -3255,11 +3335,11 @@ msgstr "Fes una Donació"
#: modules/help/templates/help_about.html:119
msgid "Join project"
msgstr ""
msgstr "Suma't al projecte"
#: modules/help/templates/help_about.html:123
msgid "Translate"
msgstr ""
msgstr "Tradueix"
#: modules/help/templates/help_about.html:129
msgid "Support"
@ -3271,21 +3351,21 @@ msgstr "Forum"
#: modules/help/templates/help_about.html:138
msgid "IRC Chatroom"
msgstr ""
msgstr "Sala de xat IRC"
#: modules/help/templates/help_about.html:143
msgid "Mailing list"
msgstr ""
msgstr "Llista de correu electrònic"
#: modules/help/templates/help_base.html:21
#: modules/help/templates/help_index.html:63
#, python-format
msgid "%(box_name)s Setup"
msgstr ""
msgstr "Configuració de %(box_name)s"
#: modules/help/templates/help_contribute.html:12
msgid "The FreedomBox project welcomes contributions of all kinds."
msgstr ""
msgstr "El projecte FreedomBox accepta contribucions de qualsevol tipus."
#: modules/help/templates/help_contribute.html:18
msgid ""
@ -3295,6 +3375,10 @@ msgid ""
"into your language, hosting hackathons or install fests, and by spreading "
"the word."
msgstr ""
"Pots contribuir escrivint codi, provant i reportant errors, debatent nous "
"casos dús i aplicacions, dissenyant logotips i obres dart, oferint suport "
"als teus companys usuaris, traduint FreedomBox i les seves aplicacions al "
"teu idioma, organitzant hackathons o install fests, i difonent la iniciativa."
#: modules/help/templates/help_contribute.html:28
msgid ""
@ -3307,52 +3391,63 @@ msgid ""
"throughout the world. The FreedomBox Foundation would not exist without its "
"supporters."
msgstr ""
"També pots ajudar el projecte econòmicament <a href="
"\"https://freedomboxfoundation.org/donate/\">fent una donació</a> a la "
"FreedomBox Foundation, una organització sense ànim de lucre. Fundada el "
"2011, la FreedomBox Foundation és una entitat sense ànim de lucre amb "
"estatus 501(c)(3) amb seu a Nova York que existeix per donar suport a "
"FreedomBox. Proporciona infraestructura tècnica i serveis legals pel "
"projecte, cerca aliances i defensa FreedomBox arreu del món. La FreedomBox "
"Foundation no existiria sense els seus col·laboradors."
#: modules/help/templates/help_contribute.html:42
#: modules/power/templates/power_restart.html:27
#: modules/power/templates/power_shutdown.html:26 templates/app-header.html:65
msgid "Learn more..."
msgstr ""
msgstr "Aprèn-ne més..."
#: modules/help/templates/help_contribute.html:46
msgid "How can I help?"
msgstr ""
msgstr "Com puc ajudar?"
#: modules/help/templates/help_contribute.html:48
msgid ""
"Below is a list of opportunities for contributing to Debian. It has been "
"filtered to only show packages that are installed on this system."
msgstr ""
"A continuació hi ha una llista de maneres de contribuir a Debian. Sha "
"filtrat per mostrar només els paquets que estan instal·lats en aquest "
"sistema."
#: modules/help/templates/help_contribute.html:59
msgid "Show issues"
msgstr ""
msgstr "Mostra incidències"
#: modules/help/templates/help_contribute.html:63
msgid "Packages that will be removed from Debian testing"
msgstr ""
msgstr "Paquets que seran eliminats de Debian testing"
#: modules/help/templates/help_contribute.html:69
#: modules/help/templates/help_contribute.html:85
msgid "source package:"
msgstr ""
msgstr "paquet font:"
#: modules/help/templates/help_contribute.html:80
msgid "Packages that are not in Debian testing"
msgstr ""
msgstr "Paquets que no estan a Debian testing"
#: modules/help/templates/help_contribute.html:92
msgid "Good first issues for beginners"
msgstr ""
msgstr "Bons primers reptes per a principiants"
#: modules/help/templates/help_contribute.html:104
msgid "Issues for which the package maintainer has requested help"
msgstr ""
msgstr "Incidències per a les quals qui manté del paquet ha sol·licitat ajuda"
#: modules/help/templates/help_feedback.html:12
#, python-format
msgid "Your feedback will help us improve %(box_name)s!"
msgstr ""
msgstr "Els teus comentaris ens ajudaran a millorar %(box_name)s!"
#: modules/help/templates/help_feedback.html:18
msgid ""
@ -3360,6 +3455,9 @@ msgid ""
"improve them on our <a href=\"https://discuss.freedombox.org\" "
"target=\"_blank\"> discussion forum</a>."
msgstr ""
"Fes-nos saber les funcions que falten, les teves aplicacions preferides i "
"com podem millorar-les al nostre <a href=\"https://discuss.freedombox.org\" "
"target=\"_blank\">fòrum de discussió</a>."
#: modules/help/templates/help_feedback.html:26
msgid ""
@ -3368,10 +3466,15 @@ msgid ""
"tracker</a> to let our developers know. To report, first check if the issue "
"is already reported and then use the \"New issue\" button."
msgstr ""
"Si trobes algun error o incidència, si us plau utilitza el <a href="
"\"https://salsa.debian.org/freedombox-team/freedombox/issues\" target="
"\"_blank\">seguiment dincidències</a> per informar els nostres "
"desenvolupadors. Per informar, primer comprova si lincidència ja està "
"reportada i després utilitza el botó \"Nova incidència\"."
#: modules/help/templates/help_feedback.html:36
msgid "Thank you!"
msgstr ""
msgstr "Gràcies!"
#: modules/help/templates/help_index.html:18
#, python-format
@ -3379,6 +3482,8 @@ msgid ""
"The <a href=\"%(manual_url)s\">%(box_name)s Manual</a> is the best place to "
"start for information regarding %(box_name)s."
msgstr ""
"El <a href=\"%(manual_url)s\">Manual de %(box_name)s</a> és el millor lloc "
"per començar a trobar informació sobre %(box_name)s."
#: modules/help/templates/help_index.html:25
#, python-format
@ -3386,6 +3491,8 @@ msgid ""
"<a href=\"http://wiki.debian.org/FreedomBox\" target=\"_blank\"> "
"%(box_name)s project wiki </a> contains further information."
msgstr ""
"L<a href=\"http://wiki.debian.org/FreedomBox\" target=\"_blank\">wiki del "
"projecte %(box_name)s</a> conté més informació."
#: modules/help/templates/help_index.html:32
#, python-format
@ -3395,6 +3502,11 @@ msgid ""
"discuss\"> mailing list</a>. The list archives also contain information "
"about problems faced by other users and possible solutions."
msgstr ""
"Per sol·licitar ajuda a la comunitat de %(box_name)s, es poden publicar "
"consultes a la <a href="
"\"https://lists.alioth.debian.org/mailman/listinfo/freedombox-discuss\"> "
"llista de correu</a>. Els arxius de la llista també contenen informació "
"sobre problemes que han tingut altres usuaris i possibles solucions."
#: modules/help/templates/help_index.html:42
#, python-format
@ -3404,10 +3516,14 @@ msgid ""
"oftc.net/?randomnick=1&channels=freedombox&prompt=1\"> #freedombox</a> "
"channel using the IRC web interface."
msgstr ""
"Molts contribuïdors i usuaris de %(box_name)s també estan disponibles a la "
"xarxa IRC irc.oftc.net. Uneix-te i sol·licita ajuda al canal <a href=\"https"
"://webchat.oftc.net/?randomnick=1&amp;channels=freedombox&amp;prompt=1\"> "
"#freedombox</a> mitjançant la interfície web IRC."
#: modules/help/templates/help_manual.html:18
msgid "Download as PDF"
msgstr ""
msgstr "Descarrega-ho com a PDF"
#: modules/help/templates/help_support.html:12
#, python-format
@ -3416,12 +3532,17 @@ msgid ""
"using %(box_name)s, you can ask for help from our community of users and "
"contributors."
msgstr ""
"Si necessites ajuda per fer alguna cosa o si tens problemes utilitzant "
"%(box_name)s, pots demanar ajuda a la nostra comunitat dusuaris i "
"contribuïdors."
#: modules/help/templates/help_support.html:20
msgid ""
"Search for past discussions or post a new query on our <a href=\"https://"
"discuss.freedombox.org\" target=\"_blank\">discussion forum</a>."
msgstr ""
"Cerca discussions passades o publica una nova consulta al nostre <a href="
"\"https://discuss.freedombox.org\" target=\"_blank\">fòrum de discussió</a>."
#: modules/help/templates/help_support.html:27
msgid ""
@ -3430,6 +3551,10 @@ msgid ""
"Or send an email to our <a href=\"mailto:freedombox-discuss@alioth-lists."
"debian.net\">mailing list</a>."
msgstr ""
"També pots xatejar amb nosaltres als nostres canals IRC i Matrix "
"(connectats): <ul> <li>#freedombox a irc.oftc.net</li> <li>#freedombox\\"
":matrix.org</li> </ul> O enviar un correu electrònic a la nostra <a href="
"\"mailto:freedombox-discuss@alioth-lists.debian.net\">llista de correu</a>."
#: modules/help/templates/statuslog.html:10
msgid "Status Log"

View File

@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2025-04-12 10:24+0000\n"
"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
"PO-Revision-Date: 2025-06-14 13:01+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: German <https://hosted.weblate.org/projects/freedombox/"
"freedombox/de/>\n"
"Language: de\n"
@ -19,7 +19,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 5.11-dev\n"
"X-Generator: Weblate 5.12-dev\n"
#: config.py:103
#, python-brace-format
@ -1138,8 +1138,6 @@ msgid "Server"
msgstr "Server"
#: modules/bind/manifest.py:18
#, fuzzy
#| msgid "Resolver Status"
msgid "Resolver"
msgstr "Resolver"
@ -4698,8 +4696,6 @@ msgid "Fluent Reader Lite"
msgstr "Fluent Reader Lite"
#: modules/miniflux/manifest.py:33
#, fuzzy
#| msgid "News Feed Reader"
msgid "Fluent Reader"
msgstr "Fluent Reader"
@ -4720,8 +4716,6 @@ msgid "Newsflash"
msgstr "Newsflash"
#: modules/miniflux/manifest.py:96
#, fuzzy
#| msgid "Read"
msgid "Read You"
msgstr "Read You"
@ -9187,10 +9181,8 @@ msgid "Automatic updates are disabled."
msgstr "Automatische Aktualisierungen sind deaktiviert."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:54
#, fuzzy
#| msgid "Distribution upgrade disabled"
msgid "Distribution upgrades are disabled."
msgstr "Distributions-Upgrade deaktiviert"
msgstr "Distributions-Upgrade deaktiviert."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:58
msgid ""

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,9 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2022-10-24 18:39+0000\n"
"Last-Translator: Sunil Mohan Adapa <sunil@medhas.org>\n"
"PO-Revision-Date: 2025-06-04 15:01+0000\n"
"Last-Translator: András Szűcs "
"<andrascc86288f63c44cb5@users.noreply.hosted.weblate.org>\n"
"Language-Team: Hungarian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/hu/>\n"
"Language: hu\n"
@ -17,12 +18,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.14.2-dev\n"
"X-Generator: Weblate 5.12-dev\n"
#: config.py:103
#, python-brace-format
msgid "Static configuration {etc_path} is setup properly"
msgstr ""
msgstr "A statikus konfiguráció {etc_path} megfelelően van beállítva"
#: context_processors.py:21 views.py:168
msgid "FreedomBox"
@ -36,7 +37,7 @@ msgstr "A szolgáltatás fut: {service_name}"
#: daemon.py:222
#, python-brace-format
msgid "Listening on {kind} port {listen_address}:{port}"
msgstr "Figyelés {kind} porton: {listen_address}:{port}"
msgstr "Figyelés a {kind} porton: {listen_address}:{port}"
#: daemon.py:225
#, python-brace-format
@ -58,8 +59,11 @@ msgid "Backup app before uninstall"
msgstr "Biztonsági mentés készítése az alkalmazásról eltávolítás előtt"
#: forms.py:37
#, fuzzy
msgid "Restoring from the backup will restore app data."
msgstr ""
"A biztonsági mentésből történő visszaállítás visszaállítja az alkalmazás "
"adatait."
#: forms.py:39
msgid "Repository to backup to"
@ -114,14 +118,12 @@ msgid "System"
msgstr "Rendszer"
#: menu.py:122
#, fuzzy
#| msgid "Public Visibility"
msgid "Visibility"
msgstr "Nyilvános láthatóság"
msgstr "Láthatóság"
#: menu.py:124
msgid "Data"
msgstr ""
msgstr "Adatok"
#: menu.py:128 modules/networks/templates/connection_show.html:274
#: modules/security/__init__.py:35 modules/upgrades/manifest.py:10
@ -129,32 +131,26 @@ msgid "Security"
msgstr "Biztonság"
#: menu.py:130
#, fuzzy
#| msgid "Server Administration"
msgid "Administration"
msgstr "Szerver adminisztráció"
msgstr "Adminisztráció"
#: middleware.py:134
msgid "System is possibly under heavy load. Please retry later."
msgstr ""
"A rendszer esetleg nagy terhelés alatt áll. Kérjük, próbálja meg újra később."
#: middleware.py:147
#, fuzzy, python-brace-format
#| msgid "Public key for this %(box_name)s:"
#, python-brace-format
msgid "Page not found: {url}"
msgstr "A %(box_name)s nyilvános kulcsa:"
msgstr "Az oldal nem található: {url}"
#: middleware.py:150
#, fuzzy
#| msgid "Error During Backup"
msgid "Error running operation."
msgstr "Hiba történt a biztonsági mentés közben"
msgstr "Hiba történt a művelet végrehajtásában."
#: middleware.py:152
#, fuzzy
#| msgid "Error During Backup"
msgid "Error loading page."
msgstr "Hiba történt a biztonsági mentés közben"
msgstr "Hiba történt az oldal betöltése során."
#: modules/apache/__init__.py:32
msgid "Apache HTTP Server"
@ -206,15 +202,16 @@ msgstr "Helyi hálózati domain"
#: modules/avahi/manifest.py:14
msgid "Auto-discovery"
msgstr ""
msgstr "Automatikus felismerés"
#: modules/avahi/manifest.py:14 modules/backups/manifest.py:17
msgid "Local"
msgstr ""
msgstr "helyi"
#: modules/avahi/manifest.py:14
#, fuzzy
msgid "mDNS"
msgstr ""
msgstr "mDNS"
#: modules/backups/__init__.py:24
msgid "Backups allows creating and managing backup archives."
@ -324,6 +321,8 @@ msgid ""
"In 24 hour format. Services may become temporarily unavailable while running "
"backup operation at this time of the day."
msgstr ""
"24 órás formátumban. A szolgáltatások átmenetileg elérhetetlenné válhatnak a "
"nap ezen időszakában végzett biztonsági mentés közben."
#: modules/backups/forms.py:85 modules/backups/forms.py:107
msgid "Included apps"
@ -368,6 +367,9 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
"Válassza ki a helyi gépről felöltendő biztonsági másolatfájlt. Ennek egy "
"korábban letöltött fájlnak kell lennie, amely egy {box_name} sikeres "
"biztonsági mentés eredménye. A fájlnak .tar.gz kiterjesztésűnek kell lennie."
#: modules/backups/forms.py:154
msgid "Repository path format incorrect."
@ -482,16 +484,12 @@ msgid "Restore"
msgstr "Visszaállítás"
#: modules/backups/manifest.py:15
#, fuzzy
#| msgid "Encryption"
msgid "Encrypted"
msgstr "Titkosítás"
msgstr "Titkosított"
#: modules/backups/manifest.py:16
#, fuzzy
#| msgid "Schedule"
msgid "Schedules"
msgstr "Ütemezés"
msgstr "Ütemezések"
#: modules/backups/manifest.py:18
#, fuzzy

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2025-02-07 12:01+0000\n"
"PO-Revision-Date: 2025-06-14 13:01+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 5.10-dev\n"
"X-Generator: Weblate 5.12-dev\n"
"X-Language: nl_NL\n"
"X-Source-Language: C\n"
@ -318,6 +318,8 @@ msgid ""
"In 24 hour format. Services may become temporarily unavailable while running "
"backup operation at this time of the day."
msgstr ""
"In 24-uursformat. Diensten kunnen tijdelijk niet beschikbaar zijn tijdens "
"het maken van de back-up operatie op dit moment van de dag."
#: modules/backups/forms.py:85 modules/backups/forms.py:107
msgid "Included apps"
@ -362,6 +364,9 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
"Kies het te uploaden back-upbestand op de lokale computer. Dit bestand moet "
"zijn gedownload van het resultaat van een succesvolle back-up van een "
"{box_name}. Het moet een ..tar.gz extensie hebben."
#: modules/backups/forms.py:154
msgid "Repository path format incorrect."
@ -537,15 +542,15 @@ msgstr "Er bestaat al een archief met deze naam in de repository."
#: modules/backups/privileged.py:84
msgid "Archive with given name was not found in the repository."
msgstr ""
msgstr "Er is geen archief met deze naam gevonden in de repository."
#: modules/backups/privileged.py:90
msgid "Backup system is busy with another operation."
msgstr ""
msgstr "Back-up systeem is bezig met een andere operatie."
#: modules/backups/privileged.py:95
msgid "Not enough space left on the disk or remote location."
msgstr ""
msgstr "Niet genoeg ruimte vrij op de schijf of op afstand."
#: modules/backups/repository.py:94
msgid "Existing repository is not encrypted."
@ -974,10 +979,8 @@ msgstr "Een opmerking die helpt om het doel van dit wachtwoord te onthouden."
#: modules/bepasty/manifest.py:23 modules/deluge/manifest.py:21
#: modules/samba/manifest.py:89 modules/sharing/manifest.py:19
#: modules/syncthing/manifest.py:58 modules/transmission/manifest.py:39
#, fuzzy
#| msgid "File & Snippet Sharing"
msgid "File sharing"
msgstr "Delen van bestanden en fragmenten"
msgstr "Delen van bestanden"
#: modules/bepasty/manifest.py:23
msgid "Pastebin"
@ -1119,7 +1122,7 @@ msgstr "Server"
#: modules/bind/manifest.py:18
msgid "Resolver"
msgstr ""
msgstr "Resolver"
#: modules/bind/templates/bind.html:11
msgid "Serving Domains"
@ -1344,16 +1347,12 @@ msgid "Cockpit"
msgstr "Cockpit"
#: modules/cockpit/manifest.py:23
#, fuzzy
#| msgid "Administration"
msgid "Advanced administration"
msgstr "Beheer"
msgstr "Geavanceerd Beheer"
#: modules/cockpit/manifest.py:24
#, fuzzy
#| msgid "Sharing"
msgid "Web terminal"
msgstr "Delen"
msgstr "Web terminal"
#: modules/cockpit/manifest.py:25 modules/storage/__init__.py:47
#: modules/storage/__init__.py:319 modules/storage/__init__.py:350
@ -1371,7 +1370,7 @@ msgstr "Diensten"
#: modules/cockpit/manifest.py:28
msgid "Logs"
msgstr ""
msgstr "Logbestanden"
#: modules/cockpit/manifest.py:29 modules/performance/__init__.py:16
#: modules/performance/__init__.py:40
@ -1468,13 +1467,11 @@ msgstr "Startpagina"
#: modules/config/manifest.py:8
msgid "Logging"
msgstr ""
msgstr "Loggen"
#: modules/config/manifest.py:8
#, fuzzy
#| msgid "Advanced"
msgid "Advanced apps"
msgstr "Gevorderd"
msgstr "Gevorderde toepassingen"
#: modules/config/views.py:41
#, python-brace-format
@ -1868,16 +1865,16 @@ msgid ""
"This service uses an external service to lookup public IP address. This can "
"be configured in the privacy app."
msgstr ""
"Deze dienst gebruikt een externe dienst om het publieke IP-adres op te "
"zoeken. Dit kan in ingesteld worden in de privacy app."
#: modules/dynamicdns/__init__.py:64
msgid "Dynamic DNS Client"
msgstr "Dynamic DNS Cliënt"
#: modules/dynamicdns/__init__.py:77
#, fuzzy
#| msgid "Dynamic Domain Name"
msgid "Dynamic Domain"
msgstr "Dynamische domeinnaam"
msgstr "Dynamisch domein"
#: modules/dynamicdns/forms.py:20
msgid ""
@ -1995,10 +1992,8 @@ msgid "This field is required."
msgstr "Dit veld is vereist."
#: modules/dynamicdns/forms.py:138 modules/names/forms.py:125
#, fuzzy
#| msgid "Content package already exists."
msgid "Domain already exists."
msgstr "Informatiepakket bestaat al."
msgstr "Domein bestaat al."
#: modules/dynamicdns/manifest.py:17
#: modules/dynamicdns/templates/dynamicdns.html:25
@ -2018,10 +2013,8 @@ msgstr "Heeft publiek IP adres nodig"
#: modules/dynamicdns/templates/dynamicdns-domain-delete.html:13
#: modules/names/templates/names-domain-delete.html:13
#, fuzzy
#| msgid "Tor configuration is being updated"
msgid "App configurations will be updated."
msgstr "Tor configuratie wordt bijgewerkt"
msgstr "Toepasingsinstellingen zullen worden bijgewerkt."
#: modules/dynamicdns/templates/dynamicdns.html:10
#: modules/email/templates/email.html:20 modules/names/manifest.py:11
@ -2031,10 +2024,8 @@ msgstr "Domeinen"
#: modules/dynamicdns/templates/dynamicdns.html:14
#: modules/dynamicdns/templates/dynamicdns.html:16
#, fuzzy
#| msgid "Add Domains"
msgid "Add Domain"
msgstr "Domeinen toevoegen"
msgstr "Domein toevoegen"
#: modules/dynamicdns/templates/dynamicdns.html:26
msgid "Last update"
@ -2052,16 +2043,13 @@ msgstr "Acties"
#: modules/dynamicdns/templates/dynamicdns.html:37
#: modules/dynamicdns/templates/dynamicdns.html:72
#, fuzzy, python-format
#| msgid "View domain: %(domain)s"
#, python-format
msgid "Edit domain %(domain)s"
msgstr "Bekijk domein: %(domain)s"
msgstr "Bewerk domein: %(domain)s"
#: modules/dynamicdns/templates/dynamicdns.html:47
#, fuzzy
#| msgid "Not set"
msgid "Not yet"
msgstr "Niet ingesteld"
msgstr "Niet nu"
#: modules/dynamicdns/templates/dynamicdns.html:53
msgid "Success"
@ -2072,16 +2060,13 @@ msgid "Failed"
msgstr "Mislukt"
#: modules/dynamicdns/templates/dynamicdns.html:79
#, fuzzy, python-format
#| msgid "View domain: %(domain)s"
#, python-format
msgid "Delete domain %(domain)s"
msgstr "Bekijk domein: %(domain)s"
msgstr "Verwijder domein: %(domain)s"
#: modules/dynamicdns/templates/dynamicdns.html:91
#, fuzzy
#| msgid "Cannot test: No domains are configured."
msgid "No domains configured."
msgstr "Kan niet testen: Er zijn geen domeinen ingesteld."
msgstr "Geen domeinen ingesteld."
#: modules/dynamicdns/views.py:26 modules/dynamicdns/views.py:28
msgid "Connection timed out"
@ -2100,28 +2085,21 @@ msgid "Already up-to-date"
msgstr "Al bijgewerkt"
#: modules/dynamicdns/views.py:70
#, fuzzy
#| msgid "Dynamic Domain Name"
msgid "Add Dynamic Domain"
msgstr "Dynamische domeinnaam"
msgstr "Dynamisch domein toevoegen"
#: modules/dynamicdns/views.py:72
#, fuzzy
#| msgid "Dynamic Domain Name"
msgid "Edit Dynamic Domain"
msgstr "Dynamische domeinnaam"
msgstr "Bewerk dynamisch domein"
#: modules/dynamicdns/views.py:138 modules/names/views.py:137
#, fuzzy, python-brace-format
#| msgid "View domain: %(domain)s"
#, python-brace-format
msgid "Delete Domain {domain}?"
msgstr "Bekijk domein: %(domain)s"
msgstr "Verwijder domein: {domain}?"
#: modules/dynamicdns/views.py:145 modules/names/views.py:143
#, fuzzy
#| msgid "Client deleted."
msgid "Domain deleted."
msgstr "Client verwijderd."
msgstr "Domein verwijderd."
#: modules/ejabberd/__init__.py:29
msgid ""
@ -2259,10 +2237,8 @@ msgid "Gajim"
msgstr "Gajim"
#: modules/ejabberd/manifest.py:124 modules/matrixsynapse/manifest.py:102
#, fuzzy
#| msgid "Encryption"
msgid "Encrypted messaging"
msgstr "Encryptie"
msgstr "Versleutelde berichten"
#: modules/ejabberd/manifest.py:125 modules/matrixsynapse/manifest.py:103
#: modules/mumble/manifest.py:67
@ -2373,7 +2349,7 @@ msgstr "Meer emails"
#: modules/email/__init__.py:80
msgid "Same mailbox"
msgstr ""
msgstr "Zelfde brievenbus"
#: modules/email/__init__.py:82
msgid "My Email Aliases"
@ -2498,10 +2474,8 @@ msgid "Host/Target/Value"
msgstr "Host/Target/Value"
#: modules/email/templates/email-dns.html:50
#, fuzzy
#| msgid "Server hostname or IP address"
msgid "Reverse DNS Records for IP Addresses"
msgstr "Server hostnaam of IP adres"
msgstr "Reverse DNS Records voor IP Addressen"
#: modules/email/templates/email-dns.html:53
#, python-format
@ -2521,6 +2495,9 @@ msgid ""
"An external service is used to lookup public IP address to show in the "
"following section. This can be configured in the privacy app."
msgstr ""
"Een externe dienst wordt gebruikt om het publieke IP-adres op te zoeken om "
"in de volgende sectie te tonen. Dit kan ingesteld worden in de privacy "
"toepassing."
#: modules/email/templates/email-dns.html:76
msgid "Host"
@ -2535,6 +2512,8 @@ msgid ""
"The following domains are configured. View details to see the list of DNS "
"entries to be made for the domain."
msgstr ""
"De volgende domeinen zijn in gebruik. Bekijk details om de lijst van DNS "
"regels te zien die worden gemaakt voor het domein."
#: modules/email/templates/email.html:35
#, python-format
@ -2559,6 +2538,9 @@ msgid ""
"wiki per topic. Customize each wiki to your liking with extensions and other "
"customization options."
msgstr ""
"Elke Wiki is een klein bestand. Creëer zoveel wiki's als je wilt, zoals een "
"wiki per onderwerp. Personaliseer iedere wiki met extensies en andere "
"instelbare mogelijkheden."
#: modules/featherwiki/__init__.py:33
#, python-brace-format
@ -2596,6 +2578,8 @@ msgid ""
"Wiki title and description can be set from within the wiki. This file name "
"is independent of the wiki title."
msgstr ""
"De wiki titel en beschrijving kunnen in de wiki ingesteld worden. Deze "
"bestandsnaam is onafhankelijk van de wiki titel."
#: modules/featherwiki/forms.py:23 modules/tiddlywiki/forms.py:23
msgid "New name for the wiki file, with file extension \".html\""
@ -2607,15 +2591,15 @@ msgstr "Het bestand hernoemen heeft geen invloed op de wikinaam."
#: modules/featherwiki/forms.py:32
msgid "A Feather Wiki file with .html file extension"
msgstr ""
msgstr "Een Feather Wiki-bestand met .html extensie"
#: modules/featherwiki/forms.py:35
msgid "Feather Wiki files must be in HTML format"
msgstr ""
msgstr "Feather Wiki bestanden moeten in HTML formaat zijn"
#: modules/featherwiki/forms.py:37
msgid "Upload an existing Feather Wiki file from this computer."
msgstr ""
msgstr "Upload een bestaand Feather Wiki bestand van deze computer."
#: modules/featherwiki/manifest.py:18
#: modules/help/templates/help_about.html:108 modules/ikiwiki/manifest.py:15
@ -2698,6 +2682,8 @@ msgid ""
"<strong>Hint</strong>: You can download a copy of this wiki from within "
"Feather Wiki before deleting it."
msgstr ""
"<strong>Tip</strong>: Je kunt voor het verwijderen een kopie van deze wiki "
"downloaden vanuit Feather Wiki."
#: modules/featherwiki/templates/featherwiki_delete.html:25
#: modules/tiddlywiki/templates/tiddlywiki_delete.html:25
@ -2872,6 +2858,8 @@ msgid ""
"Initial setup has been completed. Perform the next steps to make your "
"{box_name} operational."
msgstr ""
"Startinstelling is voltooid. Doe de volgende stappen om je {box_name} te "
"kunnen gebruiken."
#: modules/first_boot/__init__.py:66
msgid "Next steps"
@ -2906,6 +2894,8 @@ msgid ""
"Automatic <a href=\"%(upgrades_url)s\" target=\"_blank\">software update</a> "
"runs daily by default. For the first time, manually run it now."
msgstr ""
"Automatische <a href=\"%(upgrades_url)s\" target=\"_blank\">software update</"
"a> draait standaard dagelijks. Doe handmatig een eerste update."
#: modules/first_boot/templates/firstboot_complete.html:30
#: modules/upgrades/templates/upgrades_configure.html:119
@ -2917,6 +2907,7 @@ msgstr "Nu bijwerken"
msgid ""
"Review <a href=\"%(privacy_url)s\" target=\"_blank\">privacy options</a>."
msgstr ""
"Bekijk de <a href=\"%(privacy_url)s\" target=\"_blank\">privacy opties</a>."
#: modules/first_boot/templates/firstboot_complete.html:49
#, python-format
@ -2924,12 +2915,15 @@ msgid ""
"Review and setup <a href=\"%(networks_url)s\" target=\"_blank\">network "
"connections</a>. Change the default Wi-Fi password, if applicable."
msgstr ""
"Bekijk en stel de <a href=\"%(networks_url)s\" target=\"_blank\""
">netwerkverbindingen</a> in. Verander je standaard Wi-Fi wachtwoord, als Wi-"
"Fi wordt gebruikt."
#: modules/first_boot/templates/firstboot_complete.html:60
#, python-format
msgid ""
"Configure a <a href=\"%(names_url)s\" target=\"_blank\">domain name</a>."
msgstr ""
msgstr "Stel een <a href=\"%(names_url)s\" target=\"_blank\">domeinnaam</a> in."
#: modules/first_boot/templates/firstboot_complete.html:70
#, python-format
@ -2944,6 +2938,8 @@ msgid ""
"Put %(box_name)s to use by installing <a href=\"%(apps_url)s\" "
"target=\"_blank\">apps</a>."
msgstr ""
"Zet %(box_name)s aan het werk door <a href=\"%(apps_url)s\" target=\"_blank\""
">toepassingen</a> te installeren."
#: modules/first_boot/templates/firstboot_welcome.html:29
msgid "Start Setup"
@ -3054,7 +3050,7 @@ msgstr "Git hosting"
#: modules/gitweb/manifest.py:37
msgid "Version control"
msgstr ""
msgstr "Versiebeheer"
#: modules/gitweb/manifest.py:37
msgid "Developer tool"
@ -3115,7 +3111,7 @@ msgstr "Wijzig repository"
#: modules/gnome/__init__.py:18
msgid ""
"GNOME is a desktop environment that focuses on simplicity and ease of use."
msgstr ""
msgstr "GNOME is een desktopomgeving die focust op eenvoud en gebruiksgemak."
#: modules/gnome/__init__.py:21
#, python-brace-format
@ -3125,12 +3121,19 @@ msgid ""
"suite, and other basic utilities are available. You may install further "
"graphical applications using the software center provided within."
msgstr ""
"Deze toepassing maakt van deze {box_name} een desktop computer als er een "
"monitor, toetsenbord en muis aangesloten is. Een browser, kantoorprogramma's "
"en andere basisprogramma's worden al meegeleverd. Meer grafische "
"toepassingen zijn te installeren in het Software Centrum in deze omgeving."
#: modules/gnome/__init__.py:26
msgid ""
"This app is not suitable for low-end hardware. It requires at least 4GiB of "
"RAM, 4GiB of disk space and a GPU capable of basic 3D acceleration."
msgstr ""
"Deze toepassing is niet bruikbaar op zeer beperkte systemen. Er is minimaal "
"4GiB RAM, 4GiB opslagruimte en een videokaart die basis 3D ondersteuning "
"heeft."
#: modules/gnome/__init__.py:30
#, python-brace-format
@ -3154,7 +3157,7 @@ msgstr "Browser"
#: modules/gnome/manifest.py:11
msgid "Office suite"
msgstr ""
msgstr "Kantoortoepassingen"
#: modules/gnome/manifest.py:12
msgid "Software store"
@ -3166,7 +3169,7 @@ msgstr "GUI"
#: modules/gnome/manifest.py:14
msgid "Graphical apps"
msgstr ""
msgstr "Grafische toepassingen"
#: modules/help/__init__.py:33 modules/help/templates/help_index.html:14
#: templates/help-menu.html:8 templates/help-menu.html:14
@ -3840,10 +3843,8 @@ msgid "Offline reader"
msgstr "Offline lezer"
#: modules/kiwix/manifest.py:25
#, fuzzy
#| msgid "Archive name"
msgid "Archival"
msgstr "Archiefnaam"
msgstr "Archivering"
#: modules/kiwix/manifest.py:26 modules/shadowsocks/manifest.py:19
#: modules/shadowsocksserver/manifest.py:18 modules/tor/manifest.py:60
@ -4533,10 +4534,8 @@ msgid "totem"
msgstr "totem"
#: modules/minidlna/manifest.py:116
#, fuzzy
#| msgid "Simple Media Server"
msgid "Media server"
msgstr "Simple Media Server"
msgstr "Media server"
#: modules/minidlna/manifest.py:116
msgid "Television"
@ -4547,10 +4546,8 @@ msgid "UPnP"
msgstr "UPnP"
#: modules/minidlna/manifest.py:116
#, fuzzy
#| msgid "MiniDLNA"
msgid "DLNA"
msgstr "MiniDLNA"
msgstr "DLNA"
#: modules/minidlna/views.py:33
msgid "Updated media directory"
@ -4584,7 +4581,7 @@ msgstr "Voer een gebruikersnaam in voor de gebruiker."
#: modules/miniflux/forms.py:16
msgid "Enter a strong password with a minimum of 6 characters."
msgstr ""
msgstr "Voer een sterk wachtwoord in met een minimum van 6 tekens."
#: modules/miniflux/forms.py:18
msgid "Password confirmation"
@ -4631,10 +4628,8 @@ msgid "RSS Guard"
msgstr "RSS Guard"
#: modules/miniflux/manifest.py:138 modules/ttrss/manifest.py:55
#, fuzzy
#| msgid "News Feed Reader"
msgid "Feed reader"
msgstr "News Feed Reader"
msgstr "Feed lezer"
#: modules/miniflux/manifest.py:138 modules/ttrss/manifest.py:55
msgid "News aggregation"
@ -4801,16 +4796,16 @@ msgstr "Domeindiensten"
#: modules/names/__init__.py:69
msgid "Domain (regular)"
msgstr ""
msgstr "Domein (normaal)"
#: modules/names/__init__.py:178
msgid "Package systemd-resolved is installed"
msgstr ""
msgstr "Pakket systemd-resolved is geïnstalleerd"
#: modules/names/__init__.py:232
#, python-brace-format
msgid "Resolve domain name: {domain}"
msgstr ""
msgstr "Resolve domeinnaam: {domain}"
#: modules/names/components.py:14
msgid "All"
@ -4974,10 +4969,8 @@ msgid "Error setting hostname: {exception}"
msgstr "Hostnaam instellen mislukt: {exception}"
#: modules/names/views.py:117
#, fuzzy
#| msgid "Domain Name"
msgid "Add Domain Name"
msgstr "Domeinnaam"
msgstr "Toevoegen domeinnaam"
#: modules/networks/__init__.py:19
msgid ""
@ -5942,7 +5935,7 @@ msgstr ""
#: modules/networks/templates/wifi_scan.html:14
msgid "No Wi-Fi device detected."
msgstr ""
msgstr "Geen WiFi apparaat gevonden."
#: modules/networks/templates/wifi_scan.html:21
#, python-format
@ -6341,10 +6334,8 @@ msgstr "VPN server"
#: modules/openvpn/manifest.py:60 modules/pagekite/manifest.py:17
#: modules/wireguard/manifest.py:45
#, fuzzy
#| msgid "Removable Media"
msgid "Remote access"
msgstr "Verwisselbare Media"
msgstr "Toegang op afstand"
#: modules/openvpn/templates/openvpn.html:12
msgid "Profile"
@ -6519,13 +6510,11 @@ msgstr "Deze dienst bestaat al"
#: modules/pagekite/manifest.py:16
msgid "Reachability"
msgstr ""
msgstr "Bereibaarheid"
#: modules/pagekite/manifest.py:18
#, fuzzy
#| msgid "Tunnelblick"
msgid "Tunneling"
msgstr "Tunnelblick"
msgstr "Tunneling"
#: modules/pagekite/templates/pagekite_configure.html:13
msgid "Custom Services"
@ -6741,7 +6730,7 @@ msgstr "URL voor controle van het IP-adres"
#: modules/privacy/manifest.py:10
msgid "Usage reporting"
msgstr ""
msgstr "Gebruiksrapporten"
#: modules/privacy/manifest.py:10
msgid "External services"
@ -6839,13 +6828,7 @@ msgid "IRC"
msgstr "IRC"
#: modules/radicale/__init__.py:25
#, fuzzy, python-brace-format
#| msgid ""
#| "Radicale is a CalDAV and CardDAV server. It allows synchronization and "
#| "sharing of scheduling and contact data. To use Radicale, a <a "
#| "href=\"https://radicale.org/master.html#documentation/supported-"
#| "clients\">supported client application</a> is needed. Radicale can be "
#| "accessed by any user with a {box_name} login."
#, python-brace-format
msgid ""
"Radicale is a CalDAV and CardDAV server. It allows synchronization and "
"sharing of scheduling and contact data. To use Radicale, a <a href=\"https://"
@ -6853,10 +6836,10 @@ msgid ""
"a> is needed. Radicale can be accessed by any user with a {box_name} login."
msgstr ""
"Radicale is een CalDAV en CardDAV server. Het biedt synchronisatie en delen "
"van agenda- en contactgegevens. Om Radicale te gebruiken is een <a "
"href=\"https://radicale.org/master.html#documentation/supported-"
"clients\">ondersteunde clienttoepassing</a> nodig. Radicale kan worden "
"benaderd door elke {box_name} gebruiker."
"van agenda- en contactgegevens. Om Radicale te gebruiken is een <a href="
"\"https://radicale.org/master.html#supported-clients\">ondersteunde "
"clienttoepassing</a> nodig. Radicale kan worden benaderd door elke {box_name}"
" gebruiker."
#: modules/radicale/__init__.py:31
msgid ""
@ -7303,8 +7286,6 @@ msgid "Strict"
msgstr "Strikt"
#: modules/searx/manifest.py:17
#, fuzzy
#| msgid "Web Search"
msgid "Web search"
msgstr "Zoeken op het Internet"
@ -7326,10 +7307,8 @@ msgstr ""
"SSH server en andere diensten die door wachtwoorden worden afgeschermd."
#: modules/security/manifest.py:10
#, fuzzy
#| msgid "Automatic"
msgid "Automatic bans"
msgstr "Automatisch"
msgstr "Automatische bans"
#: modules/security/manifest.py:10
msgid "Reports"
@ -7476,7 +7455,7 @@ msgstr "Bladwijzers"
#: modules/shaarli/manifest.py:34
msgid "Link blog"
msgstr ""
msgstr "Link blog"
#: modules/shaarli/manifest.py:34
msgid "Single user"
@ -7547,16 +7526,12 @@ msgid "Encryption method. Must match setting on server."
msgstr "Encryptie methode. Moet overeenkomen met de instelling van de server."
#: modules/shadowsocks/manifest.py:20 modules/shadowsocksserver/manifest.py:19
#, fuzzy
#| msgid "Encryption"
msgid "Encrypted tunnel"
msgstr "Encryptie"
msgstr "Versleutelde tunnel"
#: modules/shadowsocks/manifest.py:21
#, fuzzy
#| msgid "Endpoint"
msgid "Entry point"
msgstr "Eindpunt"
msgstr "Aankomstpunt"
#: modules/shadowsocks/manifest.py:22 modules/shadowsocksserver/manifest.py:21
msgid "Shadowsocks"
@ -7592,10 +7567,8 @@ msgid "Encryption method. Clients must use the same setting."
msgstr "Encryptiemethode. Clients moeten dezelfde instelling gebruiken."
#: modules/shadowsocksserver/manifest.py:20
#, fuzzy
#| msgid "Endpoint"
msgid "Exit point"
msgstr "Eindpunt"
msgstr "Uitgavepunt"
#: modules/sharing/__init__.py:17
#, python-brace-format
@ -7655,10 +7628,8 @@ msgid "Shares should be either public or shared with at least one group"
msgstr "Shares moeten openbaar zijn of gedeeld worden met minimaal één groep"
#: modules/sharing/manifest.py:19 modules/zoph/manifest.py:26
#, fuzzy
#| msgid "Sharing"
msgid "Web sharing"
msgstr "Delen"
msgstr "Web delen"
#: modules/sharing/templates/sharing.html:18
#: modules/sharing/templates/sharing.html:21
@ -8048,10 +8019,8 @@ msgid "SSH"
msgstr "SSH"
#: modules/ssh/manifest.py:22
#, fuzzy
#| msgid "Remove Location"
msgid "Remote terminal"
msgstr "Locatie verwijderen"
msgstr "terminal op afstand"
#: modules/ssh/manifest.py:22
msgid "Fingerprints"
@ -8273,8 +8242,6 @@ msgid "Other directory (specify below)"
msgstr "Andere map (hieronder aangeven)"
#: modules/storage/manifest.py:9
#, fuzzy
#| msgid "Disks"
msgid "Disks"
msgstr "Schijven"
@ -8283,10 +8250,8 @@ msgid "Usage"
msgstr "Gebruik"
#: modules/storage/manifest.py:9
#, fuzzy
#| msgid "Automatic"
msgid "Auto-mount"
msgstr "Automatisch"
msgstr "Automatisch koppelen"
#: modules/storage/manifest.py:9
msgid "Expand partition"
@ -8457,7 +8422,7 @@ msgstr "Upload een bestaand TiddlyWiki bestand van deze computer."
#: modules/tiddlywiki/manifest.py:22
msgid "Journal"
msgstr ""
msgstr "Journaal"
#: modules/tiddlywiki/manifest.py:23
msgid "Digital garden"
@ -8859,10 +8824,8 @@ msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:9
#: modules/upgrades/templates/upgrades-dist-upgrade.html:11
#: modules/upgrades/templates/upgrades_configure.html:16
#, fuzzy
#| msgid "Distribution update started"
msgid "Distribution Update"
msgstr "Distributie-update gestart"
msgstr "Distributie-update"
#: modules/upgrades/__init__.py:396
msgid "Check for package holds"
@ -8897,7 +8860,7 @@ msgstr "Activeer Tussentijdse Software Updates (aanbevolen)"
#: modules/upgrades/manifest.py:10
msgid "Reboots"
msgstr ""
msgstr "Herstarts"
#: modules/upgrades/manifest.py:10
msgid "New features"
@ -8924,10 +8887,8 @@ msgid "Next"
msgstr "Volgende"
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:11
#, fuzzy
#| msgid "Could not start distribution update"
msgid "Confirm Distribution Update?"
msgstr "Kan distributie-update niet starten"
msgstr "Distributie-update bevestigen?"
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:21
#, python-format
@ -8942,28 +8903,32 @@ msgid ""
"Take a full backup of all apps and data before performing a distribution "
"update."
msgstr ""
"Maak een volledige back-up van alle toepassingen en gegevens voordat een "
"distributie update wordt gedaan."
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:38
msgid ""
"The process will take several hours. Most apps will be unavailable during "
"this time."
msgstr ""
"Dit proces kan uren duren. De meeste toepassingen zijn niet bruikbaar "
"gedurende deze tijd."
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:44
msgid ""
"Don't interrupt the process by shutting down or interrupting power to the "
"machine."
msgstr ""
"Dit proces niet onderbreken door de machine af te sluiten of de stroom te "
"onderbreken."
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:50
msgid "If the process is interrupted, you should be able to continue it."
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-confirm.html:66
#, fuzzy
#| msgid "Could not start distribution update"
msgid "Confirm & Start Distribution Update"
msgstr "Kan distributie-update niet starten"
msgstr "Bevestig en start distributie update"
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:15
msgid ""
@ -8974,7 +8939,7 @@ msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:21
msgid "Distribution update has completed. Reboot the machine, if necessary."
msgstr ""
msgstr "De distributie update is klaar. Herstart de machine als dat nodig is."
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:25
#, python-format
@ -8993,10 +8958,8 @@ msgid ""
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:42
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Go to Distribution Update"
msgstr "Upgrade van distributie testen"
msgstr "Ga naar distributie update"
#: modules/upgrades/templates/upgrades-dist-upgrade-notification.html:46
#: modules/upgrades/templates/upgrades-new-release.html:22
@ -9023,18 +8986,16 @@ msgid ""
"Distribution update is currently running. This operation may take several "
"hours. Most apps will be unavailable during this period."
msgstr ""
"Er wordt op het moment een distributie update gedaan. Dit proces kan uren "
"duren. De meeste toepassingen zijn niet bruikbaar gedurende deze tijd."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:50
#, fuzzy
#| msgid "Automatic upgrades disabled"
msgid "Automatic updates are disabled."
msgstr "Automatisch bijwerken uitgeschakeld"
msgstr "Automatisch bijwerken uitgeschakeld."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:54
#, fuzzy
#| msgid "Distribution upgrade disabled"
msgid "Distribution upgrades are disabled."
msgstr "Distributie bijwerken uitgeschakeld"
msgstr "Distributie bijwerken is uitgeschakeld."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:58
msgid ""
@ -9047,47 +9008,38 @@ msgid "Your current distribution is mixed or not understood."
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:72
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Current Distribution:"
msgstr "Upgrade van distributie testen"
msgstr "Huidige distributie:"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:74
#, fuzzy
#| msgid "unknown error"
msgid "Unknown or mixed"
msgstr "Onbekende fout"
msgstr "Onbekend of gemengd"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:77
msgid "Rolling release distribution"
msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:84
#, fuzzy, python-format
#| msgid "Delete site %(site)s"
#, python-format
msgid "Released: %(date)s."
msgstr "Verwijder site %(site)s"
msgstr "Gepubliceerd: %(date)s."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:91
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Next Stable Distribution:"
msgstr "Upgrade van distributie testen"
msgstr "Volgende stabiele distributie:"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:93
#, fuzzy
#| msgid "unknown"
msgid "Unknown"
msgstr "onbekend"
msgstr "Onbekend"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:99
#, python-format
msgid "Likely release: %(date)s."
msgstr ""
msgstr "Waarschijnlijke publicatie: %(date)s."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:107
msgid "Next stable distribution is not available yet."
msgstr ""
msgstr "Er is nog geen nieuwe stabiele distributie beschikbaar."
#: modules/upgrades/templates/upgrades-dist-upgrade.html:113
#, python-format
@ -9129,22 +9081,16 @@ msgstr ""
#: modules/upgrades/templates/upgrades-dist-upgrade.html:157
#: modules/upgrades/templates/upgrades-dist-upgrade.html:172
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Start Distribution Update"
msgstr "Upgrade van distributie testen"
msgstr "Start distributie-update"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:162
#, fuzzy
#| msgid "Test Distribution Upgrade"
msgid "Continue Distribution Update"
msgstr "Upgrade van distributie testen"
msgstr "Doorgaan met distributie update"
#: modules/upgrades/templates/upgrades-dist-upgrade.html:167
#, fuzzy
#| msgid "Starting distribution upgrade test."
msgid "Start Distribution Update (for testing)"
msgstr "Start de distributie upgrade test."
msgstr "Start de distributie update (naar testing)"
#: modules/upgrades/templates/upgrades-new-release.html:9
#, python-format
@ -9224,10 +9170,8 @@ msgid "Error when configuring unattended-upgrades"
msgstr "Fout bij het instellen van automatische upgrades"
#: modules/upgrades/views.py:117
#, fuzzy
#| msgid "Starting distribution upgrade test."
msgid "Started distribution update."
msgstr "Start de distributie upgrade test."
msgstr "Distributie upgrade gestart."
#: modules/upgrades/views.py:153
msgid "Upgrade process started."
@ -9415,10 +9359,8 @@ msgid "Manage accounts"
msgstr "Gebruikers beheren"
#: modules/users/manifest.py:8
#, fuzzy
#| msgid "Permissions"
msgid "App permissions"
msgstr "Toegangsrechten"
msgstr "Toepassingsrechten"
#: modules/users/templates/users_change_password.html:11
#, python-format
@ -9962,7 +9904,7 @@ msgstr ""
#: modules/wordpress/manifest.py:26
msgid "Content management system"
msgstr ""
msgstr "Inhoud management systeem"
#: modules/zoph/__init__.py:25
#, python-brace-format

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2025-04-09 13:07+0000\n"
"PO-Revision-Date: 2025-06-25 22:04+0000\n"
"Last-Translator: Besnik Bleta <besnik@programeshqip.org>\n"
"Language-Team: Albanian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/sq/>\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 5.11-dev\n"
"X-Generator: Weblate 5.13-dev\n"
#: config.py:103
#, python-brace-format

View File

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-21 20:08-0400\n"
"PO-Revision-Date: 2024-12-27 01:03+0000\n"
"Last-Translator: James Valleroy <jvalleroy@mailbox.org>\n"
"PO-Revision-Date: 2025-06-30 09:01+0000\n"
"Last-Translator: தமிழ்நேரம் <anishprabu.t@gmail.com>\n"
"Language-Team: Tamil <https://hosted.weblate.org/projects/freedombox/"
"freedombox/ta/>\n"
"Language: ta\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 5.10-dev\n"
"X-Generator: Weblate 5.13-dev\n"
#: config.py:103
#, python-brace-format
@ -26,7 +26,7 @@ msgstr "நிலையான உள்ளமைவு {etc_path} சரிய
#: context_processors.py:21 views.py:168
msgid "FreedomBox"
msgstr ""
msgstr "ஃப்ரீடோம்பாக்ச்"
#: daemon.py:124
#, python-brace-format
@ -101,7 +101,7 @@ msgstr "உலாவியில் உள்ள மொழி விருப்
#: menu.py:116 templates/base.html:120
msgid "Home"
msgstr ""
msgstr "வீடு"
#: menu.py:117 templates/base.html:129
msgid "Apps"
@ -681,7 +681,7 @@ msgstr "காப்புப்பிரதி இருப்பிடத்
#: modules/backups/templates/backups_repository.html:88
msgid "Download"
msgstr ""
msgstr "பதிவிறக்கம்"
#: modules/backups/templates/backups_repository.html:114
msgid "No archives currently exist."
@ -2637,7 +2637,7 @@ msgstr "இந்த கணினியிலிருந்து ஏற்க
#: modules/help/templates/help_about.html:108 modules/ikiwiki/manifest.py:15
#: modules/mediawiki/manifest.py:25 modules/tiddlywiki/manifest.py:19
msgid "Wiki"
msgstr ""
msgstr "விக்கி"
#: modules/featherwiki/manifest.py:18 modules/infinoted/manifest.py:46
#: modules/tiddlywiki/manifest.py:20
@ -2648,7 +2648,7 @@ msgstr "குறிப்பு"
#: modules/mediawiki/manifest.py:25 modules/tiddlywiki/manifest.py:21
#: modules/wordpress/manifest.py:26
msgid "Website"
msgstr ""
msgstr "வலைத்தளம்"
#: modules/featherwiki/manifest.py:18 modules/tiddlywiki/manifest.py:25
msgid "Quine"
@ -3213,7 +3213,7 @@ msgstr "கையேடு"
#: modules/help/views.py:93 templates/help-menu.html:27
#: templates/help-menu.html:28
msgid "Get Support"
msgstr ""
msgstr "ஆதரவை பெறு"
#: modules/help/__init__.py:45 modules/help/templates/help_feedback.html:9
#: modules/help/views.py:87 templates/help-menu.html:33
@ -3225,13 +3225,13 @@ msgstr "கருத்துக்களை சமர்ப்பிக்க
#: modules/help/templates/help_contribute.html:9 modules/help/views.py:76
#: templates/help-menu.html:39 templates/help-menu.html:40
msgid "Contribute"
msgstr ""
msgstr "பங்களிப்பு"
#: modules/help/__init__.py:53 templates/base.html:216 templates/base.html:219
#: templates/help-menu.html:46 templates/help-menu.html:47
#: templates/index.html:96
msgid "About"
msgstr ""
msgstr "பற்றி"
#: modules/help/templates/help_about.html:25 templates/messages.html:23
msgid "Success:"
@ -3322,11 +3322,11 @@ msgstr ""
#: modules/help/templates/help_about.html:97
msgid "Learn"
msgstr ""
msgstr "அறிக"
#: modules/help/templates/help_about.html:116 templates/toolbar.html:19
msgid "Donate"
msgstr ""
msgstr "நன்கொடை"
#: modules/help/templates/help_about.html:119
msgid "Join project"
@ -3338,7 +3338,7 @@ msgstr "மொழிபெயர்த்திடு"
#: modules/help/templates/help_about.html:129
msgid "Support"
msgstr ""
msgstr "உதவி"
#: modules/help/templates/help_about.html:133
msgid "Forum"
@ -6943,7 +6943,7 @@ msgstr "நாட்காட்டி"
#: modules/radicale/manifest.py:91 modules/roundcube/manifest.py:23
msgid "Contacts"
msgstr ""
msgstr "தொடர்புகள்"
#: modules/radicale/manifest.py:91 modules/sogo/manifest.py:75
msgid "CalDAV"
@ -7018,7 +7018,7 @@ msgstr ""
#: modules/roundcube/manifest.py:23
msgid "Email"
msgstr ""
msgstr "மின்னஞ்சல்"
#: modules/rssbridge/__init__.py:21
msgid ""
@ -10248,7 +10248,7 @@ msgstr "விரலிடைத் தோல்"
#: templates/clients.html:28
msgid "Launch"
msgstr ""
msgstr "ஏவுதல்"
#: templates/clients.html:53
msgid "GNU/Linux"

View File

@ -33,7 +33,7 @@ class BackupsApp(app_module.App):
app_id = 'backups'
_version = 3
_version = 4
def __init__(self) -> None:
"""Create components for the app."""

View File

@ -211,6 +211,8 @@ def is_mounted(mount_point: str) -> bool:
@privileged
def setup(path: str):
"""Create repository if it does not already exist."""
_create_backup_data_directory()
try:
_run(['borg', 'info', path], check=True)
except subprocess.CalledProcessError:
@ -221,6 +223,17 @@ def setup(path: str):
_init_repository(path, encryption='none')
def _create_backup_data_directory():
"""Create the backups-data with proper permissions."""
old_umask = os.umask(0o077)
try:
BACKUPS_DATA_PATH.mkdir(exist_ok=True)
BACKUPS_DATA_PATH.chmod(0o700)
shutil.chown(BACKUPS_DATA_PATH, 'root', 'root')
finally:
os.umask(old_umask)
def _init_repository(path: str, encryption: str,
encryption_passphrase: str | None = None):
"""Initialize a local or remote borg repository."""
@ -467,7 +480,6 @@ def _assert_app_id(app_id):
def dump_settings(app_id: str, settings: dict[str, int | float | bool | str]):
"""Dump an app's settings to a JSON file."""
_assert_app_id(app_id)
BACKUPS_DATA_PATH.mkdir(exist_ok=True)
settings_path = BACKUPS_DATA_PATH / f'{app_id}-settings.json'
settings_path.write_text(json.dumps(settings))

View File

@ -20,7 +20,7 @@ from plinth.privileged import service as service_privileged
from plinth.signals import domain_added, domain_removed
from plinth.utils import format_lazy, gettext_noop
from . import aliases, manifest, privileged
from . import aliases, dovecot, manifest, privileged
_description = [
_('This is a complete email server solution using Postfix, Dovecot, '
@ -52,7 +52,7 @@ class EmailApp(plinth.app.App):
app_id = 'email'
_version = 6
_version = 7
def __init__(self) -> None:
"""Initialize the email app."""
@ -95,21 +95,12 @@ class EmailApp(plinth.app.App):
'dovecot-lmtpd', 'dovecot-managesieved', 'dovecot-ldap',
'rspamd', 'redis-server', 'openssl'
], conflicts=['exim4-base', 'exim4-config', 'exim4-daemon-light'],
conflicts_action=Packages.ConflictsAction.REMOVE)
conflicts_action=Packages.ConflictsAction.REMOVE,
rerun_setup_on_upgrade=True)
self.add(packages)
dropin_configs = DropinConfigs('dropin-configs-email', [
'/etc/apache2/conf-available/email-freedombox.conf',
'/etc/dovecot/conf.d/05-freedombox-passdb.conf',
'/etc/dovecot/conf.d/05-freedombox-userdb.conf',
'/etc/dovecot/conf.d/15-freedombox-auth.conf',
'/etc/dovecot/conf.d/15-freedombox-mail.conf',
'/etc/dovecot/conf.d/90-freedombox-imap.conf',
'/etc/dovecot/conf.d/90-freedombox-lmtp.conf',
'/etc/dovecot/conf.d/90-freedombox-mailboxes.conf',
'/etc/dovecot/conf.d/90-freedombox-master.conf',
'/etc/dovecot/conf.d/90-freedombox-tls.conf',
'/etc/dovecot/conf.d/freedombox-ldap.conf.ext',
'/etc/fail2ban/jail.d/dovecot-freedombox.conf',
'/etc/postfix/freedombox-aliases.cf',
'/etc/rspamd/local.d/freedombox-logging.inc',
@ -121,10 +112,24 @@ class EmailApp(plinth.app.App):
dropin_configs_sieve = DropinConfigs('dropin-configs-email-sieve', [
'/etc/dovecot/freedombox-sieve/learn-ham.sieve',
'/etc/dovecot/freedombox-sieve/learn-spam.sieve',
'/etc/dovecot/freedombox-sieve-after/sort-spam.sieve',
'/etc/dovecot/conf.d/95-freedombox-sieve.conf'
'/etc/dovecot/freedombox-sieve-after/sort-spam.sieve'
])
self.add(dropin_configs_sieve)
dropin_configs_dovecot = DovecotDropinConfigs(
'dropin-configs-email-dovecot', [
'/etc/dovecot/conf.d/05-freedombox-passdb.conf',
'/etc/dovecot/conf.d/05-freedombox-userdb.conf',
'/etc/dovecot/conf.d/15-freedombox-auth.conf',
'/etc/dovecot/conf.d/15-freedombox-mail.conf',
'/etc/dovecot/conf.d/90-freedombox-imap.conf',
'/etc/dovecot/conf.d/90-freedombox-lmtp.conf',
'/etc/dovecot/conf.d/90-freedombox-mailboxes.conf',
'/etc/dovecot/conf.d/90-freedombox-master.conf',
'/etc/dovecot/conf.d/90-freedombox-tls.conf',
'/etc/dovecot/conf.d/95-freedombox-sieve.conf',
'/etc/dovecot/conf.d/freedombox-ldap.conf.ext'
])
self.add(dropin_configs_dovecot)
listen_ports = [(25, 'tcp4'), (25, 'tcp6'), (465, 'tcp4'),
(465, 'tcp6'), (587, 'tcp4'), (587, 'tcp6')]
@ -212,13 +217,15 @@ class EmailApp(plinth.app.App):
# Enable drop-in configuration files component for sieve (temporarily)
# to ensure that sievec can compile.
self.get_component('dropin-configs-email-sieve').enable()
self.get_component('dropin-configs-email-dovecot').enable()
service_privileged.try_restart('dovecot')
privileged.setup_spam()
# Restart daemons
service_privileged.try_restart('postfix')
service_privileged.try_restart('dovecot')
service_privileged.try_restart('rspamd')
if self.is_enabled():
service_privileged.restart('postfix')
service_privileged.restart('dovecot')
service_privileged.restart('rspamd')
# Expose to public internet
if old_version == 0:
@ -228,6 +235,20 @@ class EmailApp(plinth.app.App):
service_privileged.try_restart('rspamd')
class DovecotDropinConfigs(DropinConfigs):
"""Configure dovecot based on its package version."""
def get_target_path(self, path):
"""Return Path object for a target path."""
version = '2.3'
if dovecot.is_version_24():
version = '2.4'
target_path = super().get_target_path(path)
target_path = target_path.parent / version / target_path.name
return target_path
def _get_first_admin():
"""Return an admin user in the system or None if non exist."""
from django.contrib.auth.models import User

View File

@ -0,0 +1,20 @@
# Do not edit this file. Manage your settings on FreedomBox.
# See:
# https://doc.dovecot.org/main/core/config/auth/passdb.html
# https://doc.dovecot.org/main/howto/active_directory.html
#
# For passdb, the passwd driver looks up using NSS. In FreedomBox, NSS is
# configured to lookup LDAP with the help of libnss-ldapd. Lookup using passdb
# would have been sufficient if FreedomBox allowed all its users to login using
# pam. However, by default, FreedomBox disallows all users but 'admin' group to
# login. Hence, the need for LDAP lookup.
#
passdb freedombox-ldap {
driver = ldap
ldap_uris = ldapi:///
ldap_base = dc=thisbox
ldap_bind = yes
ldap_bind_userdn = uid=%{user},ou=users,dc=thisbox
ldap_filter = (&(objectClass=posixAccount)(uid=%{user}))
}

View File

@ -0,0 +1,32 @@
# Do not edit this file. Manage your settings on FreedomBox.
# See:
# https://doc.dovecot.org/main/core/config/auth/userdb.html
#
# Users in FreedomBox are not expected to access mail by logging into the
# system. Storing the mail in single location instead of home directories and
# with single UID/GID simplifies security reasoning and backup/restore
# operations.
#
# When FreedomBox has multiple domains a user is expected to get a mailbox that
# is same across the domains. Changing an domain name is not uncommon in
# FreedomBox. So, authenticate and store mails based on username only instead of
# including domain names in storage path.
#
# Directories are created under /var/mail as necessary by dovecot. Permissions
# for newly created directories are inherited from parent directory. FreedomBox
# will remove all permissions for 'others' from /var/mail to ensure that mail is
# not read by non-root users.
#
# userdb provides lookup for three parameters after authentication of a user.
# These parameters are uid, gid, and home directory of the user. If these do not
# change from user to user, a 'static' database type with fixed values is
# sufficient as userdb.
userdb freedombox-static {
driver = static
fields {
uid=mail
gid=mail
home=/var/mail/%{user | username | lower}
}
}

View File

@ -0,0 +1,10 @@
# Do not edit this file. Manage your settings on FreedomBox.
# See:
# https://doc.dovecot.org/main/core/config/auth/basic.html
# https://doc.dovecot.org/main/core/config/auth/databases/ldap.html#username
# Outlook and Windows Mail work only with LOGIN mechanism, not the standard PLAIN
auth_mechanisms = plain login
auth_username_format = %{user | lower}

View File

@ -0,0 +1,18 @@
# Do not edit this file. Manage your settings on FreedomBox.
# See: https://doc.dovecot.org/main/core/config/mail_location.html
# Use sdbox, a format specific to dovecot, for storing mails. The format allows
# better performance with some IMAP queries. When this is combined with Full
# Text Search (FTS), users will get optimal web and desktop mail experience.
# Don't pick mdbox format because is requires regular expunge maintenance. We
# have enabled btrfs filesystem compression by default.
mail_driver = sdbox
mail_path = ~/mail
# We try to deliver all mail using a single UID 'mail' and a single GID 'mail'.
# In Debian, UID of mail user is 8 and GID of mail user is 8 as set in
# /usr/share/base-passwd/{passwd|group}.master. By default first valid UID in
# dovecot is 500.
first_valid_uid = 8
last_valid_uid = 8

View File

@ -0,0 +1,11 @@
# Do not edit this file. Manage your settings on FreedomBox.
# Make rspamd learn spam/ham when the user marks mails as junk or not junk.
# https://doc.dovecot.org/main/core/config/sieve/overview.html
# https://doc.dovecot.org/main/core/plugins/sieve.html
protocol imap {
mail_plugins {
imap_sieve = yes
}
}

View File

@ -0,0 +1,12 @@
# Do not edit this file. Manage your settings on FreedomBox.
# See:
# https://doc.dovecot.org/main/core/config/sieve/overview.html
# https://doc.dovecot.org/main/core/plugins/sieve.html
# Enable the sieve plugin to sort mail during delivery using sieve scripts.
protocol lmtp {
mail_plugins {
sieve = yes
}
}

View File

@ -0,0 +1,72 @@
# Do not edit this file. Manage your settings on FreedomBox.
# Mark various mailboxes with special use flags (RFC 6154). Various names used
# in mail clients for mailboxes: https://www.imapwiki.org/SpecialUse
# See:
# https://doc.dovecot.org/main/core/config/mail_location.html#custom-namespace-location
namespace inbox {
# Archive
mailbox Archive {
auto = subscribe
special_use = \Archive
}
mailbox Archives { # Thunderbird
auto = no
special_use = \Archive
}
# Drafts
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
# Sent
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox "Sent Items" { # Outlook 2010/2013
auto = no
special_use = \Sent
}
mailbox "Sent Messages" { # iOS
auto = no
special_use = \Sent
}
# Junk
mailbox Junk {
auto = subscribe
autoexpunge = 60d
special_use = \Junk
}
mailbox Spam { # KMail, K-9 Mail
auto = no
autoexpunge = 60d
special_use = \Junk
}
mailbox "Junk E-mail" { # Outlook 2010
auto = no
autoexpunge = 60d
special_use = \Junk
}
mailbox INBOX.Junk {
auto = no
autoexpunge = 60d
special_use = \Junk
}
# Trash
mailbox Trash {
auto = subscribe
autoexpunge = 60d
special_use = \Trash
}
mailbox INBOX.Trash {
auto = no
autoexpunge = 60d
special_use = \Trash
}
}

View File

@ -0,0 +1,21 @@
# Do not edit this file. Manage your settings on FreedomBox.
# Listen on Unix domain sockets for postfix to use dovecot SASL authentication
# and for postfix to deliver mail using dovecot to local mailboxes. See:
# https://doc.dovecot.org/main/howto/sasl/postfix.html#postfix-and-dovecot-sasl
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0600
user = postfix
group = postfix
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}

View File

@ -0,0 +1,12 @@
# Do not edit this file. Manage your settings on FreedomBox.
# Mozilla Guideline v5.7, Dovecot 2.3.21, OpenSSL 3.4.0, intermediate.
# Generated 2025-07-16: https://ssl-config.mozilla.org/
# See: https://doc.dovecot.org/main/core/config/ssl.html
ssl = required
ssl_min_protocol = TLSv1.2
ssl_server_prefer_ciphers = client
ssl_curve_list = X25519:prime256v1:secp384r1
ssl_cipher_list = 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:DHE-RSA-CHACHA20-POLY1305

View File

@ -0,0 +1,43 @@
# Do not edit this file. Manage your settings on FreedomBox.
# Default sieve scripts applied for delivery to all users. To move mail to Junk
# folder based on classification headers set by rspamd. See:
# https://doc.dovecot.org/main/core/plugins/sieve.html
sieve_script freedombox-after {
type = after
driver = file
path = /etc/dovecot/freedombox-sieve-after
}
sieve_plugins {
sieve_imapsieve = yes
sieve_extprograms = yes
}
sieve_global_extensions {
vnd.dovecot.pipe = yes
vnd.dovecot.environment = yes
}
# Make rspamd learn spam/ham when the user marks mails as junk or not junk.
# https://doc.dovecot.org/main/core/config/spam_reporting.html
sieve_pipe_bin_dir = /usr/bin
# When moving a mail from to Junk folder from elsewhere
mailbox Junk {
sieve_script learn-spam {
type = before
cause = copy
path = /etc/dovecot/freedombox-sieve/learn-spam.sieve
}
}
# When moving a mail from from Junk folder to elsewhere
imapsieve_from Junk {
sieve_script learn-ham {
type = before
cause = copy
path = /etc/dovecot/freedombox-sieve/learn-ham.sieve
}
}

View File

@ -0,0 +1,4 @@
# Do not edit this file. Manage your settings on FreedomBox.
# This file is not needed for Dovecot >= 2.4. It is only needed for simplifying
# compatibility with Dovecot 2.3.

View File

@ -0,0 +1,17 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Utilities to configure Dovecot."""
import apt
from plinth.utils import Version
def is_version_24():
"""Return the currently installed version of Dovecot."""
cache = apt.Cache()
try:
version = cache['dovecot-core'].installed.version
except KeyError:
return True
return Version(version) >= Version('1:2.4')

View File

@ -2,8 +2,7 @@
"""Provides privileged actions that run as root."""
from .aliases import setup_aliases
from .dkim import (get_dkim_public_key, setup_dkim,
fix_incorrect_key_ownership)
from .dkim import fix_incorrect_key_ownership, get_dkim_public_key, setup_dkim
from .domain import set_domains
from .home import setup_home
from .postfix import setup_postfix

View File

@ -10,6 +10,7 @@ See: https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/
import pathlib
from .. import postfix
from ..dovecot import is_version_24
# Mozilla Guideline v5.6, Postfix 1.17.7, OpenSSL 1.1.1d, intermediate
# Generated 2021-08
@ -68,15 +69,27 @@ def set_postfix_config(primary_domain, all_domains):
def set_dovecot_config(primary_domain, all_domains):
"""Set dovecot configuration for TLS certificates."""
is_new_version = is_version_24()
# Determine whether to prefix file paths with '<' based on version
prefix = ''
cert_naming = 'ssl_server_cert_file'
key_naming = 'ssl_server_key_file'
if not is_new_version:
prefix = '<'
cert_naming = 'ssl_cert'
key_naming = 'ssl_key'
content = f'''# This file is managed by FreedomBox
ssl_cert = </etc/dovecot/letsencrypt/{primary_domain}/cert.pem
ssl_key = </etc/dovecot/letsencrypt/{primary_domain}/privkey.pem
{cert_naming} = {prefix}/etc/dovecot/letsencrypt/{primary_domain}/cert.pem
{key_naming} = {prefix}/etc/dovecot/letsencrypt/{primary_domain}/privkey.pem
'''
for domain in all_domains:
content += f'''
local_name {domain} {{
ssl_cert = </etc/dovecot/letsencrypt/{domain}/cert.pem
ssl_key = </etc/dovecot/letsencrypt/{domain}/privkey.pem
{cert_naming} = {prefix}/etc/dovecot/letsencrypt/{domain}/cert.pem
{key_naming} = {prefix}/etc/dovecot/letsencrypt/{domain}/privkey.pem
}}
'''
cert_config = pathlib.Path('/etc/dovecot/conf.d/91-freedombox-tls.conf')

View File

@ -358,8 +358,6 @@ def _maintenance_mode():
@privileged
def dump_database():
"""Dump database to file."""
DB_BACKUP_FILE.parent.mkdir(parents=True, exist_ok=True)
with _maintenance_mode():
with DB_BACKUP_FILE.open('w', encoding='utf-8') as file_handle:
subprocess.run([

View File

@ -9,7 +9,7 @@ from plinth import app as app_module
from plinth import menu
from plinth.daemon import Daemon
from plinth.modules.backups.components import BackupRestore
from plinth.package import Packages
from plinth.package import Package, Packages
from . import manifest
@ -49,7 +49,15 @@ class PerformanceApp(app_module.App):
order=40)
self.add(menu_item)
packages = Packages('packages-performance', ['cockpit-pcp'])
packages = Packages('packages-performance', [
# For bookworm, we need cockpit-pcp (which depends on
# cockpit-bridge and pcp). For trixie, cockpit-pcp is
# replaced by cockpit-bridge, and we need to specify a
# dependency on pcp. There is some issue with having a
# virtual package specified, see #2475.
Package('cockpit-pcp') | Package('cockpit-bridge'),
'cockpit-bridge', 'pcp'
])
self.add(packages)
backup_restore = BackupRestore('backup-restore-performance',

View File

@ -38,7 +38,7 @@ class SOGoApp(app_module.App):
app_id = 'sogo'
_version = 1
_version = 2
def __init__(self) -> None:
"""Create components for the app."""

View File

@ -81,7 +81,7 @@ def _create_config(db_password: str):
SOGoTrashFolderName = "Trash";
SOGoJunkFolderName = "Junk";
SOGoIMAPServer = "imap://127.0.0.1:143/?tls=YES&tlsVerifyMode=allowInsecureLocalhost";
SOGoSieveServer = "sieve://127.0.0.14190/?tls=YES&tlsVerifyMode=allowInsecureLocalhost";
SOGoSieveServer = "sieve://127.0.0.1:4190/?tls=YES&tlsVerifyMode=allowInsecureLocalhost";
/* LDAP */
SOGoUserSources = ({{

View File

@ -46,7 +46,7 @@ distribution_info: dict = {
'trixie': {
'version': 13,
'next': 'forky',
'release_date': datetime.datetime(2025, 8, 20, tzinfo=timezone.utc),
'release_date': datetime.datetime(2025, 8, 9, tzinfo=timezone.utc),
},
'forky': {
'version': 14,
@ -116,6 +116,9 @@ def _get_sources_list_codename() -> str | None:
dists = set()
for match_ in aug.match('*'):
dist = aug.get(match_ + '/distribution')
if not dist:
continue
dist = dist.removesuffix('-updates')
dist = dist.removesuffix('-security')
dists.add(dist)

View File

@ -190,7 +190,7 @@ def test_get_status(check_auto, is_dist_upgrade_enabled,
assert status['current_release_date'] == current_date
assert status['next_codename'] == 'trixie'
assert status['next_version'] == 13
next_date = datetime_original(2025, 8, 20, tzinfo=timezone.utc)
next_date = datetime_original(2025, 8, 9, tzinfo=timezone.utc)
assert status['next_release_date'] == next_date
assert status['next_action'] == 'manual'

View File

@ -143,7 +143,6 @@ def is_public() -> bool:
@privileged
def dump_database():
"""Dump database to file."""
_db_backup_file.parent.mkdir(parents=True, exist_ok=True)
with action_utils.service_ensure_running('mysql'):
with _db_backup_file.open('w', encoding='utf-8') as file_handle:
subprocess.run([

View File

@ -2,7 +2,6 @@
"""Configuration helper for Zoph server."""
import configparser
import os
import pathlib
import re
import subprocess
@ -122,7 +121,6 @@ def dump_database():
"""
with action_utils.service_ensure_running('mysql'):
db_name = _get_db_config()['db_name']
os.makedirs(os.path.dirname(DB_BACKUP_FILE), exist_ok=True)
with open(DB_BACKUP_FILE, 'w', encoding='utf-8') as db_backup_file:
subprocess.run(['mysqldump', db_name], stdout=db_backup_file,
check=True)

View File

@ -10,7 +10,7 @@ from plinth import module_loader
from plinth.actions import privileged
def _assert_managed_dropin_config(app_id: str, path: str):
def _get_managed_dropin_config(app_id: str, path: str):
"""Check that this is a path managed by the specified app."""
module_path = module_loader.get_module_import_path(app_id)
module = importlib.import_module(module_path)
@ -25,7 +25,7 @@ def _assert_managed_dropin_config(app_id: str, path: str):
components = app.get_components_of_type(DropinConfigs)
for component in components:
if path in component.etc_paths:
return
return component
raise AssertionError('Not a managed drop-in config')
@ -37,10 +37,9 @@ def dropin_is_valid(app_id: str, path: str, copy_only: bool,
Optionally, drop the link if it is invalid.
"""
_assert_managed_dropin_config(app_id, path)
from plinth.config import DropinConfigs
etc_path = DropinConfigs.get_etc_path(path)
target = DropinConfigs.get_target_path(path)
component = _get_managed_dropin_config(app_id, path)
etc_path = component.get_etc_path(path)
target = component.get_target_path(path)
if etc_path.exists() or etc_path.is_symlink():
if (not copy_only and etc_path.is_symlink()
and etc_path.readlink() == target):
@ -59,10 +58,9 @@ def dropin_is_valid(app_id: str, path: str, copy_only: bool,
@privileged
def dropin_link(app_id: str, path: str, copy_only: bool):
"""Create a symlink from /etc/ to /usr/share/freedombox/etc."""
_assert_managed_dropin_config(app_id, path)
from plinth.config import DropinConfigs
target = DropinConfigs.get_target_path(path)
etc_path = DropinConfigs.get_etc_path(path)
component = _get_managed_dropin_config(app_id, path)
target = component.get_target_path(path)
etc_path = component.get_etc_path(path)
etc_path.parent.mkdir(parents=True, exist_ok=True)
if copy_only:
shutil.copyfile(target, etc_path)
@ -73,7 +71,6 @@ def dropin_link(app_id: str, path: str, copy_only: bool):
@privileged
def dropin_unlink(app_id: str, path: str, missing_ok: bool = False):
"""Remove a symlink in /etc/."""
_assert_managed_dropin_config(app_id, path)
from plinth.config import DropinConfigs
etc_path = DropinConfigs.get_etc_path(path)
component = _get_managed_dropin_config(app_id, path)
etc_path = component.get_etc_path(path)
etc_path.unlink(missing_ok=missing_ok)

View File

@ -31,9 +31,10 @@ def fixture_dropin_configs():
@pytest.fixture(autouse=True)
def fixture_assert_dropin_config():
def fixture_assert_dropin_config(dropin_configs):
"""Mock asserting dropin config path."""
with patch('plinth.privileged.config._assert_managed_dropin_config'):
with patch('plinth.privileged.config._get_managed_dropin_config') as mock:
mock.return_value = dropin_configs
yield
@ -95,7 +96,7 @@ def test_dropin_configs_enable_disable_symlinks(dropin_configs, tmp_path):
# Enable when a file already exists
dropin_configs.disable()
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
etc_path.touch()
dropin_configs.enable()
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
@ -108,7 +109,7 @@ def test_dropin_configs_enable_disable_symlinks(dropin_configs, tmp_path):
# When symlink already exists to correct location
dropin_configs.disable()
target_path = DropinConfigs.get_target_path('/etc/test/path1')
target_path = dropin_configs.get_target_path('/etc/test/path1')
etc_path.symlink_to(target_path)
dropin_configs.enable()
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
@ -119,7 +120,7 @@ def test_dropin_configs_enable_disable_copy_only(dropin_configs, tmp_path):
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
dropin_configs.copy_only = True
for path in ['/etc/test/path1', '/etc/path2']:
target = DropinConfigs.get_target_path(path)
target = dropin_configs.get_target_path(path)
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text('test-config-content')
@ -135,7 +136,7 @@ def test_dropin_configs_enable_disable_copy_only(dropin_configs, tmp_path):
# Enable when a file already exists with wrong content
dropin_configs.disable()
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
etc_path.write_text('x-invalid-content')
dropin_configs.enable()
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
@ -182,7 +183,7 @@ def test_dropin_config_diagnose_symlinks(dropin_configs, tmp_path):
# A file exists instead of symlink
dropin_configs.disable()
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
etc_path.touch()
results = dropin_configs.diagnose()
assert results[0].result == 'failed'
@ -204,7 +205,7 @@ def test_dropin_config_diagnose_copy_only(dropin_configs, tmp_path):
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
dropin_configs.copy_only = True
for path in ['/etc/test/path1', '/etc/path2']:
target = DropinConfigs.get_target_path(path)
target = dropin_configs.get_target_path(path)
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text('test-config-content')
@ -221,7 +222,7 @@ def test_dropin_config_diagnose_copy_only(dropin_configs, tmp_path):
# A symlink exists instead of a copied file
dropin_configs.disable()
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
etc_path.symlink_to('/blah')
results = dropin_configs.diagnose()
assert results[0].result == 'failed'