Compare commits

...

21 Commits

Author SHA1 Message Date
James Valleroy
5d099e13cb
Release v25.16~bpo13+1 to trixie-backports 2025-11-29 09:15:19 -05:00
James Valleroy
8ae32a9d11 freedombox Debian release 25.16
-----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmklpbwWHGp2YWxsZXJv
 eUBtYWlsYm94Lm9yZwAKCRB3wMdee2UICPLqD/4/MOQb5Qv+UWYC6h2tSNUs2BFr
 Fk6RoUJv0nDDrsDRYQvA9eqAWH3uqa53CUlSBP0i4aDyZnGttuZtTcekfp8z6aQP
 oF9npspNgkvmHaD+jF2AJFTg52lJ96vtKAHcWXpI92GzpmOLJVT5EVAMDSSerahO
 9wmuBQEhDFzi0tao2AKk1OBifTYx3lBXtTqzRAJ6CtEF0ekyTE3A2ofWsFbb34QI
 7GYlLYE8PNxz7tfvSN/PRt9jeLrht7OQQtVDH+AAjXt78bd3WQm4NN1RLmz3J6OG
 pHcOb4VTTt7pOabMHMmU8OWTqKm9I/mcd3oRDlTFZV1Rywlu4wy8K6xPAHKXBYfN
 xG284qTInVuS2V9XEPJD0MZpqOfIqNNsZ6BTgyo6g13d3RgD7gHpthhLPR/ywawo
 aEhnyQjpw5jMwiCFviq1R9+cDlbir2atE0sViU/B19LJ0RbXq2smqwWqngpTrG89
 Bd9t7LbWawSKiLhjNhMl0COvrUuGxHKx08yejIlIxbAjL5yL1uD2NDvzw6vqX6pU
 A2hkxQ6/hr6K3uUwxXzSRuJTTW8GFn5ubb1kzria2E5p0ZFAczmLUQDWjf8REliy
 S6o39cLxi2f5OfergGmmd5VRanRskCYeykB9oRtdtzQBs74oqIdYRCpqEeGj0csX
 l0+85hNWEZMkQTAbqw==
 =5eh0
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEfWrbdQ+RCFWJSEvmd8DHXntlCAgFAmkq/94WHGp2YWxsZXJv
 eUBtYWlsYm94Lm9yZwAKCRB3wMdee2UICEmuD/9XEEm2J7+lbPzDTgvAjcIqnNW+
 5g6QLJHqY7CMdSgvYr/MWZn76tm8mRllXOI7yvbLBBvg0KtodPaEcaDNaWpw3wON
 +vJBQflPJBYWTdS0Ho+ZlLB0nP+VyQtliZ/bXuT2m6mkqlA9e/VBeZ1wVkUOIWpu
 CD5NQdA/yNJiyS0hh9M4VxyO06GAyOjTdn6+Mem7byW/0GNui9Tx4+Pq6FeLELEO
 qjpBT+JH34n1yaqsiYIryt611x/kpDLubomig/7mrRk6YK8lXEqqG1l7uZz1LaR1
 aS0JSCtDqfiIgDGMB13VZBt6BMwCvXac0MkrNRwzXxYXrx1SumGKhvThi49tzmLr
 kqsmKf3BeqmHkR20YJlcNApBZ1Z/iG4dtSz18dsAexB7lcYec2c5wPldgbTHQlwP
 ZWx+ufX0OfLglRQE5Yy6iwHqRSQK48eIszHwYNXgTpdSb7OUhY5JHBsC9OXFZk4W
 lhDpdtypIQXepaZddlGCa9MhXUKGWCQHgVWSc9hM8sixZSOVcrhUGYzGqEvUxlPq
 jwOQ+gNCip06vUjWL8RwBTWvo/fEXJtBV4PPGuZygtVMux8woijeAsK6efA8yuQI
 B3bXFDedf99ZcRdZeVEDYKojbTdedNusnbuTOfYhEEYT2s04GvJy9qa+vQscFIMn
 rZK7GWHk9YHP4yw0pQ==
 =6qUh
 -----END PGP SIGNATURE-----

Merge tag 'v25.16' into debian/trixie-backports

freedombox Debian release 25.16
2025-11-29 09:14:53 -05:00
James Valleroy
d63324160a
Release v25.16 to unstable 2025-11-24 20:44:22 -05:00
James Valleroy
d16c18be37
doc: Fetch latest manual 2025-11-24 20:44:09 -05:00
James Valleroy
3fe62bac0b
locale: Update translation strings 2025-11-24 20:22:18 -05:00
Sunil Mohan Adapa
ffecd1411b
jsxc: Update content security policy to prevent style errors
- Without the CSP, during loading there are no errors in the console. However,
during chatting, some styling related error show up.

Tests:

- Ensure that there are no CSP related errors in the browser console.

Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-21 22:31:27 -05:00
Sunil Mohan Adapa
a66c011f0b
jsxc: Fix missing dependencies
Fixes: #2547.

- Earlier, FreedomBox itself depended on Bootstrap 4 as needed by the room we
built for JSXC. Since FreedomBox moved to Bootstrap 5 this library is no longer
available for JSXC. libjs-jsxc itself depends on libjs-bootstrap which is of
version 3.

- Also fix the path for jquery-slimscroll. This is was likely updated for Trixie
cycle.

Tests:

- Connect to JSXC with two different browsers. Add contacts. Initiate chat and
send messages.

- Re-run app setup and it succeeds.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-21 22:31:14 -05:00
Sunil Mohan Adapa
a10ba40001
dynamicdns: Use only IPv4 for GnuDIP protocol
- The following messages was seen on the ddns.freedombox.org server:
"Unserviceable IP address from <ipv6_address>: user <username>.fbx.one - IP:
<ipv6_address>". This is due to code that checks for validity of incoming IP
address and fails. The current configuration only handles IPv4 address. Even if
this restriction is lifted, GnuDIP code does not contain code to add/remove AAAA
records.

- Fix this by forcing GnuDIP HTTP update requests to go on IPv4.

Tests:

- Copy the code for _request_get_ipv4() into a python3 console and run
_request_get_ipv4('https://ddns.freedombox.org/ip'). Do this on a dual stack
machine with both public IPv4 and IPv6 addresses. Only IPv4 address returned.
Changing the AF to AF_INET6 returns only the IPv6 address.

- Take a test DDNS account offline. Configure it in FreedomBox stable VM. The IP
address is properly updated.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-21 22:03:10 -05:00
Roman Akimov
7b93932868
Translated using Weblate (Russian)
Currently translated at 100.0% (1875 of 1875 strings)
2025-11-21 02:51:20 +00:00
Sunil Mohan Adapa
6c3b2e1f82
package: Prevent freedombox's deps from removal during app uninstall
- If an app declares dependency on package that is also a dependency for
freedombox, then during the app's uninstall, the dependency is attempt to be
removed and will fail (because freedombox package will be held state).

- Add freedombox (and thus its dependencies) to the list packages that should be
removed from list of packages to be removed during app uninstall.

- In test case, update list of packages attempted removal as the 'freedombox'
package is installed only in some environments.

Tests:

- Uninstall janus works. Log messages show that libjs-bootstrap5 and
node-popper2 are in the list of packages originally set to removed during app
uninstall but are later filtered out.

- Run pytest with 'freedombox' package installed and ensure all tests pass.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-17 13:03:06 -05:00
Sunil Mohan Adapa
b6bade7d06
janus: Update the video room code from latest upstream
- Bootswatch is a theme library for bootstrap. In Debian, only 3.x version of
the package is available. It is compatible with bootstrap 3.x but not bootstrap
5. Drop the theming altogether and use the basic bootstrap style (which is
already very close to the theme).

- Updated copyright year, mention the video room files in debian/copyright.

- Drop libjs-spin.js which is no longer used by the updated code.

- Change bootstrap version to 5.x from the earlier 4.x. Also add node-popper2
library (needed by bootstrap5 and video room code) as explicit dependency.

- Add missing style for btn-default class dropped in bootstrap 5.

- .simulcast-button CSS style is not longer needed as updated code used flex box
with .d-flex bootstrap class.

Tests:

- Compare the files in janus source code around Mar 2022 with the files in
FreedomBox source code before this patch. Compare latest janus source code with
the files after this patch. Both sets of changes are very similar.

- Connect to video room using two browser windows. Connection is successful and
2 video streams are shown in each of the browser windows.

- Styling looks close to the demo on janus website and is acceptable.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-17 13:03:02 -05:00
Sunil Mohan Adapa
94c344573b
janus: Relax content security policy for the video room
- Needed for the new video room code to run without CSP errors in the browser
console. JS error happens immediately after loading the page before Janus
initialization. Styling related errors happen after joining the room despite
eliminating use of'style=' attributes from JS code.

Tests:

- The video room works for a conference without showing any
Content-Security-Policy header related errors in the Firefox developer console.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-17 13:02:59 -05:00
Sunil Mohan Adapa
32520c7c89
janus: Allow app to be installed from Debian unstable
- Janus is currently not installable in Trixie because Janus was temporarily
removed during the release process of Trixie.

- Installing it from unstable, despite the instability is better than keeping
the app unavailable. Users have reported using the app.

Tests:

- Restarting the service after applying the patch leads to setup for upgrades
app to run. Apt preferences for janus packages are set. App is shown as
available. It can be installed.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-17 13:02:56 -05:00
Sunil Mohan Adapa
2467d6a033
middleware: Implement middleware for common headers such as CSP
- This allows overriding these headers in individual pages easily instead of
relaxing global policy.

- Drop the obsolete CSP directive "block-all-mixed-content" and avoid a console
warning in Firefox.

Tests:

- Load a page and notice in the browser developer tools that the three headers
referrer-policy, content-security-policy, and x-content-type-options are set as
before.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2025-11-17 13:02:52 -05:00
Dietmar
3eef1d9324
Translated using Weblate (Italian)
Currently translated at 47.5% (891 of 1875 strings)
2025-11-13 13:51:19 +00:00
Dietmar
7d38f49dd8
Translated using Weblate (German)
Currently translated at 98.9% (1856 of 1875 strings)
2025-11-13 13:51:16 +00:00
Besnik Bleta
601de6d0e3
Translated using Weblate (Albanian)
Currently translated at 99.7% (1871 of 1875 strings)
2025-11-12 07:51:36 +00:00
Максим Горпиніч
cdfdacabad
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (1875 of 1875 strings)
2025-11-12 07:51:34 +00:00
Jiří Podhorecký
d4c4900b1d
Translated using Weblate (Czech)
Currently translated at 100.0% (1875 of 1875 strings)
2025-11-12 07:51:22 +00:00
大王叫我来巡山
8f87d658a6
Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 61.5% (1154 of 1875 strings)
2025-11-12 07:51:19 +00:00
Burak Yavuz
117932e66f
Translated using Weblate (Turkish)
Currently translated at 100.0% (1875 of 1875 strings)
2025-11-12 07:51:17 +00:00
64 changed files with 1377 additions and 1020 deletions

View File

@ -47,48 +47,6 @@
RedirectMatch "^/$" "/plinth"
</IfFile>
##
## Disable sending Referer (sic) header from FreedomBox web interface to
## external websites. This improves privacy by not disclosing FreedomBox
## domains/URLs to external domains. Apps such as blogs which want to popularize
## themselves with referrer header may still do so.
##
## A strict Content Security Policy.
## - @fonts are allowed only from FreedomBox itself.
## - <frame>/<iframe> sources are disabled.
## - <img> sources are allowed only from FreedomBox itself.
## - Manifest file is not allowed as there is none yet.
## - <audio>, <video>, <track> tags are not allowed yet.
## - <object>, <embed>, <applet> tags are not allowed yet.
## - Allow JS from FreedomBox itself (no inline and attribute scripts).
## - Allow inline CSS and CSS files from Freedombox itself.
## - Web worker sources are allowed only from FreedomBox itself (for JSXC).
## - All other fetch sources including Ajax are not allowed from FreedomBox
## itself.
## - <base> tag is not allowed.
## - No plugins types are alllowed since object-src is 'none'.
## - Form action should be to FreedomBox itself.
## - This interface may be not embedded in <frame>, <iframe>, etc. tags.
## - When serving HTTPS, don't allow HTTP assets.
##
## Enable strict sandboxing enabled with some exceptions:
## - Allow running Javascript.
## - Allow popups as sometimes we use <a target=_blank>
## - Allow popups to have different sandbox requirements as we launch apps' web
## clients.
## - Allow forms to support configuration forms.
## - Allow policies to treat same origin differently from other origins
## - Allow downloads such as backup tarballs.
##
## Disable browser guessing of MIME types. FreedoBox already sets good content
## types for all the common file types.
##
<LocationMatch "^/(plinth|freedombox)">
Header set Referrer-Policy 'same-origin'
Header set Content-Security-Policy "font-src 'self'; frame-src 'none'; img-src 'self' data:; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'self'; style-src 'self'; worker-src 'self'; default-src 'self'; base-uri 'none'; sandbox allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-same-origin allow-downloads; form-action 'self'; frame-ancestors 'none'; block-all-mixed-content;"
Header set X-Content-Type-Options 'nosniff'
</LocationMatch>
##
## On all sites, provide FreedomBox on a default path: /plinth
##

46
debian/changelog vendored
View File

@ -1,3 +1,49 @@
freedombox (25.16~bpo13+1) trixie-backports; urgency=medium
* Rebuild for trixie-backports.
-- James Valleroy <jvalleroy@mailbox.org> Sat, 29 Nov 2025 09:14:58 -0500
freedombox (25.16) unstable; urgency=medium
[ Burak Yavuz ]
* Translated using Weblate (Turkish)
[ 大王叫我来巡山 ]
* Translated using Weblate (Chinese (Simplified Han script))
[ Jiří Podhorecký ]
* Translated using Weblate (Czech)
[ Максим Горпиніч ]
* Translated using Weblate (Ukrainian)
[ Besnik Bleta ]
* Translated using Weblate (Albanian)
[ Dietmar ]
* Translated using Weblate (German)
* Translated using Weblate (Italian)
[ Sunil Mohan Adapa ]
* middleware: Implement middleware for common headers such as CSP
* janus: Allow app to be installed from Debian unstable
* janus: Relax content security policy for the video room
* janus: Update the video room code from latest upstream
* package: Prevent freedombox's deps from removal during app uninstall
* dynamicdns: Use only IPv4 for GnuDIP protocol
* jsxc: Fix missing dependencies
* jsxc: Update content security policy to prevent style errors
[ Roman Akimov ]
* Translated using Weblate (Russian)
[ James Valleroy ]
* locale: Update translation strings
* doc: Fetch latest manual
-- James Valleroy <jvalleroy@mailbox.org> Mon, 24 Nov 2025 20:30:35 -0500
freedombox (25.15~bpo13+1) trixie-backports; urgency=medium
* Rebuild for trixie-backports.

5
debian/copyright vendored
View File

@ -143,7 +143,10 @@ License: ISC
Files: plinth/modules/janus/static/icons/janus.png
plinth/modules/janus/static/icons/janus.svg
Copyright: 2014-2022 Meetecho
plinth/modules/janus/static/janus-video-room.css
plinth/modules/janus/static/janus-video-room.js
plinth/modules/janus/templates/janus_video_room.html
Copyright: 2014-2025 Meetecho
License: GPL-3 with OpenSSL exception
Files: plinth/modules/kiwix/static/icons/kiwix.png

View File

@ -8,6 +8,23 @@ 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.16 (2025-11-24) ==
=== Highlights ===
* dynamicdns: Use only IPv4 for GnuDIP protocol
* janus: Allow app to be installed from Debian unstable
* jsxc: Fix missing dependencies
=== Other Changes ===
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, German, Italian, Russian, Turkish, Ukrainian
* janus: Relax content security policy for the video room
* janus: Update the video room code from latest upstream
* jsxc: Update content security policy to prevent style errors
* middleware: Implement middleware for common headers such as CSP
* package: Prevent freedombox's deps from removal during app uninstall
== FreedomBox 25.15 (2025-11-10) ==
=== Highlights ===

View File

@ -8,6 +8,23 @@ 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.16 (2025-11-24) ==
=== Highlights ===
* dynamicdns: Use only IPv4 for GnuDIP protocol
* janus: Allow app to be installed from Debian unstable
* jsxc: Fix missing dependencies
=== Other Changes ===
* locale: Update translations for Albanian, Chinese (Simplified Han script), Czech, German, Italian, Russian, Turkish, Ukrainian
* janus: Relax content security policy for the video room
* janus: Update the video room code from latest upstream
* jsxc: Update content security policy to prevent style errors
* middleware: Implement middleware for common headers such as CSP
* package: Prevent freedombox's deps from removal during app uninstall
== FreedomBox 25.15 (2025-11-10) ==
=== Highlights ===

View File

@ -3,4 +3,4 @@
Package init file.
"""
__version__ = '25.15'
__version__ = '25.16'

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-04-16 02:28+0000\n"
"Last-Translator: MohammedSaalif <2300031323@kluniversity.in>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/freedombox/"
@ -3539,7 +3539,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3557,7 +3566,7 @@ msgstr "خادم ويب"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3847,14 +3856,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2020-06-10 15:41+0000\n"
"Last-Translator: aiman an <an1f3@hotmail.com>\n"
"Language-Team: Arabic (Saudi Arabia) <https://hosted.weblate.org/projects/"
@ -3529,7 +3529,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3547,7 +3556,7 @@ msgstr "خادم ويب"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3839,14 +3848,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@ -3509,7 +3509,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3525,7 +3534,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3813,14 +3822,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-09-24 03:02+0000\n"
"Last-Translator: 109247019824 "
"<109247019824@users.noreply.hosted.weblate.org>\n"
@ -3655,7 +3655,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3671,7 +3680,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3995,14 +4004,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-04-01 03:02+0000\n"
"Last-Translator: MURALA SAI GANESH <saiganeshmurala@gmail.com>\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/freedombox/"
@ -3558,7 +3558,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3574,7 +3583,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3862,14 +3871,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+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/"
@ -3938,7 +3938,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3954,7 +3963,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4242,14 +4251,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-09-28 07:02+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-12 07:51+0000\n"
"Last-Translator: Jiří Podhorecký <j.podhorecky@volny.cz>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/freedombox/"
"freedombox/cs/>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n"
"X-Generator: Weblate 5.14-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: plinth/config.py:103
#, python-brace-format
@ -3900,7 +3900,19 @@ msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
"<a href=\"{coturn_url}\">Coturn</a> je vyžadován pro použití systému Janus."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Poznámka:</strong> Tato aplikace je často aktualizována. Lze ji "
"nainstalovat pouze v případě, že jsou časté aktualizace funkcí povoleny v "
"aplikaci <a href=\"{upgrades_url}\">Aktualizace softwaru</a>."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3916,7 +3928,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Webové konference"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4251,17 +4263,6 @@ msgstr ""
"Nainstalujte aplikaci <a href=\"{coturn_url}\">Coturn</a> nebo "
"nakonfigurujte externí server."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Poznámka:</strong> Tato aplikace je často aktualizována. Lze ji "
"nainstalovat pouze v případě, že jsou časté aktualizace funkcí povoleny v "
"aplikaci <a href=\"{upgrades_url}\">Aktualizace softwaru</a>."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4360,20 +4361,16 @@ msgstr ""
"href=\"%(config_url)s\">nastavte</a> alespoň jednu doménu."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
"requires uninstalling and reinstalling the app which will wipe app's data."
msgstr ""
"Doména Matrix serveru je nastavená na <em>%(domain_name)s</em>. "
"Identifikátory uživatelů budou mít podobu <em>@uzivatelske_jmeno:"
"%(domain_name)s</em>. Změna doménového názvu po úvodním nastavení není v "
"současnosti podporována."
"Doména serveru Matrix je nastavena na <em>%(domain_name)s</em>. ID uživatelů "
"budou vypadat takto: <em>@username:%(domain_name)s</em>. Změna názvu domény "
"vyžaduje odinstalování a opětovnou instalaci aplikace, což vymaže data "
"aplikace."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4416,10 +4413,8 @@ msgid "Unlimited"
msgstr "Neomezený"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:78
#, fuzzy
#| msgid "Feed generator"
msgid "Federation"
msgstr "Generátor kanálů"
msgstr "Federace"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:81
#, python-format
@ -4430,6 +4425,12 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse je nakonfigurován tak, aby spolupracoval s ostatními servery "
"Matrix na internetu. To umožňuje uživatelům %(box_name)s účastnit se "
"chatovacích místností hostovaných jinde a uživatelům Matrix na jiných "
"serverech účastnit se chatovacích místností hostovaných zde. Pokud máte "
"problémy s federací, vyzkoušejte <a "
"href=\"%(tester_url)s#%(domain_name)s\">nástroj pro testování federace</a>."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -7275,19 +7276,15 @@ msgstr ""
"href=\"{users_url}\">každý uživatel </a> patřící do skupiny feed-reader."
#: plinth/modules/rssbridge/__init__.py:28
#, fuzzy, python-brace-format
#| msgid ""
#| "You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
#| "href=\"{ttrss_url}\">Tiny Tiny RSS</a> to follow various websites. When "
#| "adding a feed, enable authentication and use your {box_name} credentials."
#, python-brace-format
msgid ""
"You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"RSS-Bridge můžete používat s <a href=\"{miniflux_url}\">Miniflux</a> nebo <a "
"href=\"{ttrss_url}\">Tiny Tiny RSS</a> pro sledování různých webových "
"stránek. Při přidávání kanálu povolte ověřování a použijte své přihlašovací "
"RSS-Bridge můžete použít s <a href=\"{miniflux_url}\">Miniflux</a> nebo <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> k sledování různých webových "
"stránek. Při přidávání zdroje povolte ověřování a použijte své přihlašovací "
"údaje {box_name}."
#: plinth/modules/rssbridge/__init__.py:49

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Danish <https://hosted.weblate.org/projects/freedombox/"
@ -4040,7 +4040,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -4058,7 +4067,7 @@ msgstr "Webserver"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4407,14 +4416,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-11-11 01:13+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-13 13:51+0000\n"
"Last-Translator: Dietmar <sagen@permondes.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/freedombox/"
"freedombox/de/>\n"
@ -3982,7 +3982,20 @@ msgstr ""
"Zur Verwendung von Janus ist <a href=\"{coturn_url}\">Coturn</a> "
"erforderlich."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Hinweis:</strong> Diese App erhält regelmäßig Funktionsupdates. Sie "
"kann nur installiert werden, wenn in der App <a href=\"{upgrades_url}"
"\">Software Aktualisierungen</a> die Option für regelmäßige Funktionsupdates "
"aktiviert ist."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3998,7 +4011,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Web-Konferenz"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4338,18 +4351,6 @@ msgstr ""
"Installiere die <a href=\"{coturn_url}\">Coturn</a>-App oder konfiguriere "
"einen externen Server."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Hinweis:</strong> Diese App erhält regelmäßig Funktionsupdates. Sie "
"kann nur installiert werden, wenn in der App <a href=\"{upgrades_url}"
"\">Software Aktualisierungen</a> die Option für regelmäßige Funktionsupdates "
"aktiviert ist."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4451,19 +4452,16 @@ msgstr ""
"Matrix Synapse nutzen zu können."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
"requires uninstalling and reinstalling the app which will wipe app's data."
msgstr ""
"Ihre Matrix-Server-Domain ist auf <em>%(domain_name)s</em> gesetzt. Benutzer-"
"IDs erscheinen als <em>Nutzername:%(domain_name)s</em>. Änderungen der "
"Domain nach der ersten Konfiguration werden derzeit nicht unterstützt."
"Die Matrix-Serverdomäne ist auf <em>%(domain_name)s</em> eingestellt. "
"Benutzer-IDs sehen wie folgt aus: <em>@username:%(domain_name)s</em>. Um den "
"Domänennamen zu ändern, muss die App deinstalliert und neu installiert "
"werden, wodurch die Daten der App gelöscht werden."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4520,6 +4518,12 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse ist so konfiguriert, dass es mit anderen Matrix-Servern im "
"Internet zusammenarbeitet. Dadurch können %(box_name)s-Benutzer an Räumen "
"teilnehmen, die woanders gehostet werden, und Matrix-Benutzer auf anderen "
"Servern können an Räumen teilnehmen, die hier gehostet werden. Wenn Sie "
"Probleme mit der Föderation haben, probieren Sie das <a "
"href=\"%(tester_url)s#%(domain_name)s\">Föderationstest-Tool</a> ."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -7418,20 +7422,16 @@ msgstr ""
"a> der zur Feed-Reader-Gruppe gehört, aufgerufen werden."
#: plinth/modules/rssbridge/__init__.py:28
#, fuzzy, python-brace-format
#| msgid ""
#| "You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
#| "href=\"{ttrss_url}\">Tiny Tiny RSS</a> to follow various websites. When "
#| "adding a feed, enable authentication and use your {box_name} credentials."
#, python-brace-format
msgid ""
"You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"Sie können RSS-Bridge mit <a href=\"{miniflux_url}\">Miniflux</a> oder <a "
"href=\"{ttrss_url}\">Tiny Tiny RSS</a> verwenden, um verschiedenen "
"Internetseiten zu folgen. Aktivieren Sie beim Hinzufügen eines Feeds die "
"Authentifizierung und verwenden Sie Ihre {box_name}-Anmeldeinformationen."
"href=\"{nextcloud_url}\">Nextcloud News</a> verwenden, um verschiedene "
"Websites zu verfolgen. Wenn Sie einen Feed hinzufügen, aktivieren Sie die "
"Authentifizierung und verwenden Sie Ihre {box_name}-Anmeldedaten."
#: plinth/modules/rssbridge/__init__.py:49
msgid "Read and subscribe to news feeds"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -3510,7 +3510,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3526,7 +3535,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3814,14 +3823,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:20+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/freedombox/"
@ -4103,7 +4103,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -4121,7 +4130,7 @@ msgstr "Διακομιστής Διαδικτύου (Web Server)"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4467,14 +4476,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2024-11-01 17:00+0000\n"
"Last-Translator: gallegonovato <fran-carro@hotmail.es>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/freedombox/"
@ -4011,7 +4011,16 @@ msgstr "Se incluye una sala de videoconferencia simple."
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "Para usar Janus se necesita <a href=\"{coturn_url}\">Coturn</a> ."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -4029,7 +4038,7 @@ msgstr "Servidor Web"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4377,14 +4386,6 @@ msgstr ""
"Instalar la app <a href=\"{coturn_url}\">Coturn</a> o configurar un servidor "
"externo."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-07-20 18:01+0000\n"
"Last-Translator: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>\n"
"Language-Team: Estonian <https://hosted.weblate.org/projects/freedombox/"
@ -3515,7 +3515,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3531,7 +3540,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3819,14 +3828,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/freedombox/"
@ -3931,7 +3931,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3949,7 +3958,7 @@ msgstr "سرور وب"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4289,14 +4298,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Plinth 0.6\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2016-01-31 22:24+0530\n"
"Last-Translator: Sunil Mohan Adapa <sunil@medhas.org>\n"
"Language-Team: Plinth Developers <freedombox-"
@ -4083,7 +4083,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -4101,7 +4110,7 @@ msgstr "WEB SERVER"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4446,14 +4455,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
#, fuzzy
#| msgid "Chat Server (XMPP)"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-10-30 04:24+0000\n"
"Last-Translator: Coucouf <coucouf@coucouf.fr>\n"
"Language-Team: French <https://hosted.weblate.org/projects/freedombox/"
@ -3992,7 +3992,20 @@ msgstr "Une salle de visioconférence simple est incluse."
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "<a href=\"{coturn_url}\">Coturn</a> est requis pour utiliser Janus."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Note :</strong> Cette appli est mise à jour à un rythme soutenu. "
"Elle ne peut être installée que lorsque les mises à jour fréquentes sont "
"activées depuis lappli de <a href=\"{upgrades_url}\">Mise à jour du "
"système</a>."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -4008,7 +4021,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Conférence Web"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4347,18 +4360,6 @@ msgstr ""
"Installez pour cela lapplication <a href=\"{coturn_url}\">Coturn</a> ou "
"bien configurez un serveur externe."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Note :</strong> Cette appli est mise à jour à un rythme soutenu. "
"Elle ne peut être installée que lorsque les mises à jour fréquentes sont "
"activées depuis lappli de <a href=\"{upgrades_url}\">Mise à jour du "
"système</a>."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-12-30 10:51+0000\n"
"Last-Translator: gallegonovato <fran-carro@hotmail.es>\n"
"Language-Team: Galician <https://hosted.weblate.org/projects/freedombox/"
@ -3528,7 +3528,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3546,7 +3555,7 @@ msgstr "Servidor web"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3836,14 +3845,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2021-01-18 12:32+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Gujarati <https://hosted.weblate.org/projects/freedombox/"
@ -3801,7 +3801,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3817,7 +3826,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4109,14 +4118,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-04-29 16:30+0000\n"
"Last-Translator: Thulasi Edhala <thulasiedhala@gmail.com>\n"
"Language-Team: Hindi <https://hosted.weblate.org/projects/freedombox/"
@ -4048,7 +4048,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -4066,7 +4075,7 @@ msgstr "वेब सर्वर"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4399,14 +4408,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "मैट्रिक्स सिनापसॅ"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-06-04 15:01+0000\n"
"Last-Translator: András Szűcs "
"<andrascc86288f63c44cb5@users.noreply.hosted.weblate.org>\n"
@ -4058,7 +4058,16 @@ msgstr ""
"A Janus használatához szükség van a <a href=\"{coturn_url}\">Coturn</a> "
"alkalmazásra."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -4076,7 +4085,7 @@ msgstr "Webszerver"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4425,14 +4434,6 @@ msgstr ""
"videóhívásokhoz. Telepítsd a <a href=\"{coturn_url}\">Coturn</a> "
"alkalmazást, vagy konfigurálj egy külső szervert."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Indonesian (FreedomBox)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/freedombox/"
@ -4000,7 +4000,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -4018,7 +4027,7 @@ msgstr "Server Web"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4361,14 +4370,6 @@ msgstr ""
"Pasang aplikasi <a href=\"{coturn_url}\">Coturn</a> atau konfigurasikan "
"server eksternal."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Sinaps Matrix"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-11-11 01:13+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-13 13:51+0000\n"
"Last-Translator: Dietmar <sagen@permondes.de>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/it/>\n"
@ -3778,7 +3778,20 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Nota:</strong> questa app riceve frequenti aggiornamenti delle "
"funzionalità. Può essere installata solo se gli aggiornamenti frequenti "
"delle funzionalità sono abilitati nell'app <a href=\"{upgrades_url}"
"\">Aggiornamento software</a>."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3794,7 +3807,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4107,18 +4120,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Nota:</strong> questa app riceve frequenti aggiornamenti delle "
"funzionalità. Può essere installata solo se gli aggiornamenti frequenti "
"delle funzionalità sono abilitati nell'app <a href=\"{upgrades_url}"
"\">Aggiornamento software</a>."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4213,20 +4214,16 @@ msgstr ""
"almeno un dominio per poter usare Matrix Synapse."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
"requires uninstalling and reinstalling the app which will wipe app's data."
msgstr ""
"Il dominio del server Matrix è impostato su <em> %(domain_name)s </em>. Gli "
"ID utente assomiglieranno a <em>@username:%(domain_name)s</em>. Il cambio "
"del nome di dominio dopo la prima configurazione, attualmente, non è "
"supportato."
"ID utente assomiglieranno a <em>@nome_utente:%(domain_name)s</em>. La "
"modifica del nome di dominio richiede la disinstallazione e la "
"reinstallazione dell'app, che cancellerà i dati dell'app."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
#, fuzzy
@ -4282,6 +4279,12 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse è configurato per funzionare con altri server Matrix su "
"Internet. Ciò consente agli utenti di %(box_name)s di partecipare a stanze "
"ospitate altrove e agli utenti Matrix su altri server di partecipare alle "
"stanze ospitate qui. Se riscontri problemi con la federazione, prova lo <a "
"href=\"%(tester_url)s#%(domain_name)s\"> strumento di verifica della "
"federazione</a>."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -6930,6 +6933,10 @@ msgid ""
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"È possibile utilizzare RSS-Bridge con <a href=\"{miniflux_url}\">Miniflux</"
"a> o <a href=\"{nextcloud_url}\">Nextcloud News</a> per seguire vari siti "
"web. Quando si aggiunge un feed, abilitare l'autenticazione e utilizzare le "
"credenziali {box_name}."
#: plinth/modules/rssbridge/__init__.py:49
msgid "Read and subscribe to news feeds"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-10-24 16:02+0000\n"
"Last-Translator: Jun Nogata <nogajun@gmail.com>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/freedombox/"
@ -3517,7 +3517,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3533,7 +3542,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3821,14 +3830,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2020-07-16 16:41+0000\n"
"Last-Translator: Yogesh <yogesh@karnatakaeducation.org.in>\n"
"Language-Team: Kannada <https://hosted.weblate.org/projects/freedombox/"
@ -3512,7 +3512,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3528,7 +3537,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3816,14 +3825,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Lithuanian <https://hosted.weblate.org/projects/freedombox/"
@ -3524,7 +3524,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3540,7 +3549,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3830,14 +3839,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:20+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Latvian <https://hosted.weblate.org/projects/freedombox/"
@ -3523,7 +3523,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3539,7 +3548,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3829,14 +3838,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2024-10-27 23:30+0000\n"
"Last-Translator: Sunil Mohan Adapa <sunil@medhas.org>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/"
@ -4051,7 +4051,16 @@ msgstr "Et enkelt videokonferanserom er med."
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -4069,7 +4078,7 @@ msgstr "Nett-tjener"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4411,14 +4420,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-09-17 09:01+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/freedombox/"
@ -3893,7 +3893,16 @@ msgstr "Er is ook een eenvoudige videoconferentieruimte."
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "Om Janus te gebruiken is <a href=\"{coturn_url}\">Coturn</a> nodig."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3909,7 +3918,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Web Conferentie"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4247,14 +4256,6 @@ msgstr ""
"videogesprekken. Installeer de <a href=\"{coturn_url}\">Coturn</a> "
"toepassing of configureer een externe server."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2024-07-13 12:09+0000\n"
"Last-Translator: Monika <adamdomenek@protonmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/freedombox/"
@ -3961,7 +3961,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3979,7 +3988,7 @@ msgstr "Serwer Web"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4285,14 +4294,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-04-09 22:41+0000\n"
"Last-Translator: tuliogit <wikigeolog@gmx.com>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/freedombox/"
@ -3957,7 +3957,16 @@ msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
"&lt;a href=\"{coturn_url}\"&gt;Coturn&lt;/a&gt; é necessário para usar Janus."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3973,7 +3982,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Conferência web"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4309,14 +4318,6 @@ msgstr ""
"vídeo. Instale o aplicativo <a href=\"{coturn_url}\">Coturn</a> ou configure "
"um servidor externo."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-09-29 19:02+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-21 02:51+0000\n"
"Last-Translator: Roman Akimov <zoompyc@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/ru/>\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Weblate 5.14-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: plinth/config.py:103
#, python-brace-format
@ -213,7 +213,7 @@ msgstr "Местный"
#: plinth/modules/avahi/manifest.py:14
msgid "mDNS"
msgstr ""
msgstr "mDNS"
#: plinth/modules/backups/__init__.py:24
msgid "Backups allows creating and managing backup archives."
@ -503,7 +503,7 @@ msgstr "Конфигурация"
#: plinth/modules/backups/manifest.py:21
msgid "Borg"
msgstr ""
msgstr "Borg"
#: plinth/modules/backups/privileged.py:34
msgid ""
@ -935,7 +935,7 @@ msgstr "Список и чтение всех файлов"
#: plinth/modules/bepasty/__init__.py:57 plinth/modules/bepasty/manifest.py:6
msgid "bepasty"
msgstr ""
msgstr "bepasty"
#: plinth/modules/bepasty/forms.py:17
msgid "Public Access (default permissions)"
@ -977,7 +977,7 @@ msgstr "Обмен файлами"
#: plinth/modules/bepasty/manifest.py:23
msgid "Pastebin"
msgstr ""
msgstr "Pastebin"
#: plinth/modules/bepasty/templates/bepasty.html:12
msgid "Manage Passwords"
@ -2457,7 +2457,7 @@ msgstr "Thunderbird"
#: plinth/modules/email/manifest.py:37
msgid "Thunderbird Mobile"
msgstr ""
msgstr "Thunderbird Mobile"
#: plinth/modules/email/manifest.py:52
msgid "FairEmail"
@ -2703,7 +2703,7 @@ msgstr "Веб-сайт"
#: plinth/modules/featherwiki/manifest.py:18
#: plinth/modules/tiddlywiki/manifest.py:25
msgid "Quine"
msgstr ""
msgstr "Quine"
#: plinth/modules/featherwiki/manifest.py:18
#: plinth/modules/nextcloud/manifest.py:56
@ -3712,7 +3712,7 @@ msgstr "Домашняя автоматизация"
#: plinth/modules/homeassistant/manifest.py:63
msgid "IoT"
msgstr ""
msgstr "IoT"
#: plinth/modules/homeassistant/manifest.py:64
#: plinth/modules/networks/manifest.py:8
@ -3725,11 +3725,11 @@ msgstr "Wi-Fi"
#: plinth/modules/homeassistant/manifest.py:65
msgid "ZigBee"
msgstr ""
msgstr "ZigBee"
#: plinth/modules/homeassistant/manifest.py:66
msgid "Z-Wave"
msgstr ""
msgstr "Z-Wave"
#: plinth/modules/homeassistant/manifest.py:67
msgid "Thread"
@ -3928,7 +3928,20 @@ msgstr "Включает в себя простую комнату видеок
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "<a href=\"{coturn_url}\">Coturn</a> необходим для использования Janus."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Примечание:</strong> Это приложение часто получает обновления. Оно "
"может быть установлено только в том случае, если в системе включено частое "
"обновление функций. <a href=\"{upgrades_url}\">Обновление программного "
"обеспечения</a> ."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3938,13 +3951,13 @@ msgstr "Видеокомната Janus"
#: plinth/modules/janus/manifest.py:16
msgid "WebRTC"
msgstr ""
msgstr "WebRTC"
#: plinth/modules/janus/manifest.py:16
msgid "Web conference"
msgstr "Веб-конференция"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4021,7 +4034,7 @@ msgstr "Управление сервером контента Kiwix"
#: plinth/modules/kiwix/__init__.py:56 plinth/modules/kiwix/manifest.py:8
msgid "Kiwix"
msgstr ""
msgstr "Kiwix"
#: plinth/modules/kiwix/forms.py:23
msgid "Content packages have to be in .zim format"
@ -4278,18 +4291,6 @@ msgstr ""
"Установите приложение <a href=\"{coturn_url}\">Coturn</a> или настройте "
"внешний сервер."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Примечание:</strong> Это приложение часто получает обновления. Оно "
"может быть установлено только в том случае, если в системе включено частое "
"обновление функций. <a href=\"{upgrades_url}\">Обновление программного "
"обеспечения</a> ."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4391,11 +4392,7 @@ msgstr ""
"мере один домен, чтобы иметь возможность использовать Matrix."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
@ -4403,8 +4400,8 @@ msgid ""
msgstr ""
"Домен сервера Matrix имеет значение <em>%(domain_name)s</em>. Идентификаторы "
"пользователей будет выглядеть как <em>@имя_пользователя:%(domain_name)s</"
"em>. Изменение имени домена после первоначальной настройки в настоящее время "
"не поддерживается."
"em>. Для изменения доменного имени требуется удалить и переустановить "
"приложение, что приведет к удалению данных приложения."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4447,10 +4444,8 @@ msgid "Unlimited"
msgstr "Неограниченное"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:78
#, fuzzy
#| msgid "Feed generator"
msgid "Federation"
msgstr "Генератор питания"
msgstr "Объединение"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:81
#, python-format
@ -4461,6 +4456,12 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse настроен для работы с другими серверами Matrix в Интернете. "
"Это позволяет пользователям %(box_name)s участвовать в комнатах, размещенных "
"на других серверах, а пользователям Matrix других серверов - в комнатах, "
"размещенных на этом сервере. Если у вас возникнут проблемы с федерацией, "
"попробуйте использовать <a href=\"%(tester_url)s#%(domain_name)s\"> "
"инструмент для тестирования федерации</a>."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -4820,7 +4821,7 @@ msgstr ""
#: plinth/modules/miniflux/__init__.py:42
#: plinth/modules/miniflux/manifest.py:10
msgid "Miniflux"
msgstr ""
msgstr "Miniflux"
#: plinth/modules/miniflux/forms.py:12
msgid "Enter a username for the user."
@ -4844,7 +4845,7 @@ msgstr "Пароли не совпадают."
#: plinth/modules/miniflux/manifest.py:18
msgid "Fluent Reader Lite"
msgstr ""
msgstr "Fluent Reader Lite"
#: plinth/modules/miniflux/manifest.py:33
msgid "Fluent Reader"
@ -4852,15 +4853,15 @@ msgstr "Беглое чтение"
#: plinth/modules/miniflux/manifest.py:46
msgid "FluxNews"
msgstr ""
msgstr "FluxNews"
#: plinth/modules/miniflux/manifest.py:61
msgid "MiniFlutt"
msgstr ""
msgstr "MiniFlutt"
#: plinth/modules/miniflux/manifest.py:71
msgid "NetNewsWire"
msgstr ""
msgstr "NetNewsWire"
#: plinth/modules/miniflux/manifest.py:86
msgid "Newsflash"
@ -5198,7 +5199,7 @@ msgstr "Ссылка"
#: plinth/modules/names/templates/names.html:104
#: plinth/modules/networks/templates/connection_show.html:268
msgid "DNS-over-TLS"
msgstr ""
msgstr "DNS-over-TLS"
#: plinth/modules/names/templates/names.html:108
msgid "DNSSEC"
@ -6246,7 +6247,7 @@ msgstr "локальная ссылка"
#: plinth/modules/networks/views.py:32
msgid "dhcp"
msgstr ""
msgstr "dhcp"
#: plinth/modules/networks/views.py:33
msgid "ignore"
@ -6506,7 +6507,7 @@ msgstr ""
#: plinth/modules/nextcloud/manifest.py:11
#: plinth/modules/nextcloud/manifest.py:18
msgid "Nextcloud"
msgstr ""
msgstr "Nextcloud"
#: plinth/modules/nextcloud/forms.py:19
msgid "Not set"
@ -7230,11 +7231,11 @@ msgstr "Контакты"
#: plinth/modules/radicale/manifest.py:91 plinth/modules/sogo/manifest.py:75
msgid "CalDAV"
msgstr ""
msgstr "CalDAV"
#: plinth/modules/radicale/manifest.py:91 plinth/modules/sogo/manifest.py:76
msgid "CardDAV"
msgstr ""
msgstr "CardDAV"
#: plinth/modules/radicale/views.py:32
msgid "Access rights configuration updated"
@ -7323,20 +7324,16 @@ msgstr ""
"фидов."
#: plinth/modules/rssbridge/__init__.py:28
#, fuzzy, python-brace-format
#| msgid ""
#| "You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
#| "href=\"{ttrss_url}\">Tiny Tiny RSS</a> to follow various websites. When "
#| "adding a feed, enable authentication and use your {box_name} credentials."
#, python-brace-format
msgid ""
"You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"Вы можете использовать RSS-Bridge с <a href=\"{miniflux_url}\">Miniflux</a> "
"или <a href=\"{ttrss_url}\">Tiny Tiny RSS</a>, чтобы следить за различными "
"сайтами. При добавлении ленты включите аутентификацию и используйте свои "
"учетные данные {box_name}."
"Вы можете использовать RSS-мост с <a href=\"{miniflux_url}\">Miniflux</a> or "
"<a href=\"{nextcloud_url}\">Nextcloud News</a> следить за различными веб-"
"сайтами. При добавлении фида включите аутентификацию и используйте свои "
"учетные данные от {box_name}."
#: plinth/modules/rssbridge/__init__.py:49
msgid "Read and subscribe to news feeds"
@ -7834,7 +7831,7 @@ msgstr "Точка входа"
#: plinth/modules/shadowsocks/manifest.py:22
#: plinth/modules/shadowsocksserver/manifest.py:21
msgid "Shadowsocks"
msgstr ""
msgstr "Shadowsocks"
#: plinth/modules/shadowsocksserver/__init__.py:26
#, python-brace-format
@ -8103,7 +8100,7 @@ msgstr "Заведомо исправное состояние"
#: plinth/modules/snapshot/manifest.py:14
msgid "Btrfs"
msgstr ""
msgstr "Btrfs"
#: plinth/modules/snapshot/templates/snapshot_delete_selected.html:12
msgid "Delete the following snapshots permanently?"
@ -8731,7 +8728,7 @@ msgstr ""
#: plinth/modules/tiddlywiki/__init__.py:64
#: plinth/modules/tiddlywiki/manifest.py:9
msgid "TiddlyWiki"
msgstr ""
msgstr "TiddlyWiki"
#: plinth/modules/tiddlywiki/forms.py:39
msgid "A TiddlyWiki file with .html file extension"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2021-04-27 13:32+0000\n"
"Last-Translator: HelaBasa <R45XvezA@protonmail.ch>\n"
"Language-Team: Sinhala <https://hosted.weblate.org/projects/freedombox/"
@ -3512,7 +3512,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3528,7 +3537,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3816,14 +3825,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:19+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Slovenian <https://hosted.weblate.org/projects/freedombox/"
@ -3771,7 +3771,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3787,7 +3796,7 @@ msgstr ""
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4087,14 +4096,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-10-14 10:07+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-12 07:51+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.14-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: plinth/config.py:103
#, python-brace-format
@ -3665,6 +3665,10 @@ msgid ""
"alarms, presence sensors, door bells, thermostats, irrigation timers, energy "
"monitors, etc."
msgstr ""
"Home Assistant është një qendër automatizimi shtëpie, me theksin te "
"kontrolli vendor dhe privatësia. Integrohet me mijëra pajisje, përfshi "
"llamba të mençura, alarme, ndijues pranie, zile dyersh, termostate, "
"kohëmatës ujitjeje, mbikëqyrës energjie, etj."
#: plinth/modules/homeassistant/__init__.py:35
msgid ""
@ -3673,6 +3677,11 @@ msgid ""
"requires additional hardware such as a ZigBee USB dongle. You need to re-run "
"setup if such hardware is added or removed."
msgstr ""
"Home Assistant mund të pikasë, formësojë dhe përdor pajisje të ndryshme në "
"rrjetin vendor. Për pajisje që përdorin protokolle të tjera, b.f. ZigBee, "
"zakonisht duhet hardware shtesë, si, fjala vjen, një marifet ZigBee USB. "
"Është e nevojshme të rikryeni ujdisjen, nëse vihet ose hiqet hardware i "
"tillë."
#: plinth/modules/homeassistant/__init__.py:39
msgid ""
@ -3680,6 +3689,9 @@ msgid ""
"An administrator account is created at this time. Home Assistant maintains "
"its own user accounts."
msgstr ""
"Ndërfaqja web e Home Assistant-it duhet ujdisur fill pasi të jetë instaluar "
"aplikacioni. Në atë kohë krijohet një llogari përgjegjësi. Home Assistant "
"mban llogaritë e veta të përdoruesve."
#: plinth/modules/homeassistant/__init__.py:43
#, python-brace-format
@ -3933,7 +3945,20 @@ msgstr ""
"<a href=\"{coturn_url}\">Coturn</a> është i domosdoshëm për të përdorur "
"Janus-in."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Shënim:</strong> Ky aplikacion merr përditësime të shpeshta "
"veçorish. Mund të instalohet vetëm nëse përditësime të shpeshta të veçorive "
"janë të aktivizuara te aplikacioni <a href=\"{upgrades_url}\">Përditësim "
"Software-i</a>."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3949,7 +3974,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Konferencë Web"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4284,18 +4309,6 @@ msgstr ""
"aplikacionin <a href=\"{coturn_url}\">Coturn</a>, ose formësoni një shërbyes "
"të jashtëm."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Shënim:</strong> Ky aplikacion merr përditësime të shpeshta "
"veçorish. Mund të instalohet vetëm nëse përditësime të shpeshta të veçorive "
"janë të aktivizuara te aplikacioni <a href=\"{upgrades_url}\">Përditësim "
"Software-i</a>."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4395,20 +4408,16 @@ msgstr ""
"përkatësi, që të jeni në gjendje të përdorni Matrix Synapse."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
"requires uninstalling and reinstalling the app which will wipe app's data."
msgstr ""
"Si përkatësi shërbyesi Matrix është caktuar <em>%(domain_name)s</em>. ID-të "
"e përdoruesve do të jenë të trajtës <em>@emërpërdoruesi:%(domain_name)s</"
"em>. Ndryshimi i emrit të përkatësisë, pas ujdisjes fillestare, aktualisht "
"smbulohet."
"Si përkatësi shërbyesi Matrix është vënër <em>%(domain_name)s</em>. ID-të e "
"përdoruesve do të jenë të trajtës <em>@emërpërdoruesi:%(domain_name)s</em>. "
"Ndryshimi i emrit të përkatësisë lyp çinstalimin dhe riinstalimin e "
"aplikacionit, çka do të spastrojë të dhënat e aplikacionit."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4451,10 +4460,8 @@ msgid "Unlimited"
msgstr "E pakufizuar"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:78
#, fuzzy
#| msgid "Feed generator"
msgid "Federation"
msgstr "Prodhues prurjesh"
msgstr "Federim"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:81
#, python-format
@ -4465,6 +4472,11 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse është formësuar të punojë me të tjerë shërbyes Matrix në "
"internet. Kjo u lejon përdoruesve të %(box_name)s të marrin pjesë në dhoma "
"që strehohen gjetkë dhe përdoruesve Matrix në shërbyes të tjerë të marrin "
"pjesë në dhoma të strehuara këtu. Nëse hasni probleme me federimin, provoni "
"<a href=\"%(tester_url)s#%(domain_name)s\"> mjetin testues të federimit</a>."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -7346,18 +7358,14 @@ msgstr ""
"\">cilido përdorues</a> pjesë e grupit të leximit të prurjeve."
#: plinth/modules/rssbridge/__init__.py:28
#, fuzzy, python-brace-format
#| msgid ""
#| "You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
#| "href=\"{ttrss_url}\">Tiny Tiny RSS</a> to follow various websites. When "
#| "adding a feed, enable authentication and use your {box_name} credentials."
#, python-brace-format
msgid ""
"You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"RSS-Bridge-in mund ta përdorni me <a href=\"{miniflux_url}\">Miniflux</a>, "
"ose <a href=\"{ttrss_url}\">Tiny Tiny RSS</a> për të ndjekur sajte të "
"RSS-Bridge-in mund ta përdorni me <a href=\"{miniflux_url}\">Miniflux</a> "
"ose <a href=\"{nextcloud_url}\">Nextcloud News</a> për të ndjekur sajte të "
"ndryshëm. Kur shtohet një prurje, aktivizoni mirëfilltësimin dhe përdorni "
"kredencialet tuaj për {box_name}."

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2022-09-14 17:20+0000\n"
"Last-Translator: ikmaak <info@ikmaak.nl>\n"
"Language-Team: Serbian <https://hosted.weblate.org/projects/freedombox/"
@ -3682,7 +3682,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3700,7 +3709,7 @@ msgstr "Web Server"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4000,14 +4009,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2024-07-30 01:31+0000\n"
"Last-Translator: bittin1ddc447d824349b2 <bittin@reimu.nl>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/freedombox/"
@ -4019,7 +4019,16 @@ msgstr "Ett enkelt videokonferensrum ingår."
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "<a href=\"{coturn_url}\">Coturn</a> krävs för att använda Janus."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -4037,7 +4046,7 @@ msgstr "Webbserver"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4385,14 +4394,6 @@ msgstr ""
"Matrix Synapse behöver en STUN/TURN-server för ljud-/videosamtal. Installera "
"<a href=\"{coturn_url}\">Coturn</a>-appen eller konfigurera en extern server."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-08-17 08:02+0000\n"
"Last-Translator: தமிழ்நேரம் <anishprabu.t@gmail.com>\n"
"Language-Team: Tamil <https://hosted.weblate.org/projects/freedombox/"
@ -3900,7 +3900,16 @@ msgstr "ஒரு எளிய வீடியோ மாநாட்டு அ
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "<a href=\"{coturn_url}\"> கோட்டர்ன் </a> சானசைப் பயன்படுத்த வேண்டும்."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "சானச்"
@ -3916,7 +3925,7 @@ msgstr "Webrtc"
msgid "Web conference"
msgstr "வலை மாநாடு"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4249,14 +4258,6 @@ msgstr ""
"href=\"{coturn_url}\"> coturn </a> பயன்பாட்டை நிறுவவும் அல்லது வெளிப்புற "
"சேவையகத்தை உள்ளமைக்கவும்."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "மேட்ரிக்ச் சினாப்ச்"

View File

@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-05-14 17:03+0000\n"
"Last-Translator: Sripath Roy Koganti <sripathroy@swecha.net>\n"
"Language-Team: Telugu <https://hosted.weblate.org/projects/freedombox/"
@ -3837,7 +3837,16 @@ msgstr "ఒక సాధారణ వీడియో కాన్ఫరెన్
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "<a href=\"{coturn_url}\">కారు</a> జానస్ ఉపయోగించడానికి అవసరం అవుతుంది."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "జాన్స్"
@ -3853,7 +3862,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "వెబ్ కాన్ఫరెన్స్"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4178,14 +4187,6 @@ msgstr ""
"Matrix Synapseకి ఆడియో/వీడియో కాల్‌ల కోసం STUN/TURN సర్వర్ అవసరం.<a href=\"{coturn_url}"
"\">Coturn</a> యాప్‌ను ఇన్‌స్టాల్ చేయండి లేదా బాహ్య సర్వర్‌ను కాన్ఫిగర్ చేయండి."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "మ్యాట్రిక్స్ సినాప్స్"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-09-24 03:01+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-12 07:51+0000\n"
"Last-Translator: Burak Yavuz <hitowerdigit@hotmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/freedombox/"
"freedombox/tr/>\n"
@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.14-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: plinth/config.py:103
#, python-brace-format
@ -3915,7 +3915,20 @@ msgstr "Basit bir video konferans odası dahildir."
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "Janus'u kullanmak için <a href=\"{coturn_url}\">Coturn</a> gereklidir."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Not:</strong> Bu uygulama sık yapılan özel özellik güncellemeleri "
"alır. Bu, yalnızca <a href=\"{upgrades_url}\">Yazılım Güncellemesi</a> "
"uygulamasında sık yapılan özellik güncellemeleri etkinleştirilirse "
"yüklenebilir."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3931,7 +3944,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Web görüşme"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4267,18 +4280,6 @@ msgstr ""
"ihtiyaç duyar. <a href={coturn_url}>Coturn</a> uygulamasını yükleyin veya "
"harici bir sunucu yapılandırın."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Not:</strong> Bu uygulama sık yapılan özel özellik güncellemeleri "
"alır. Bu, yalnızca <a href=\"{upgrades_url}\">Yazılım Güncellemesi</a> "
"uygulamasında sık yapılan özellik güncellemeleri etkinleştirilirse "
"yüklenebilir."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4378,11 +4379,7 @@ msgstr ""
"az bir etki alanı <a href=\"%(config_url)s\">yapılandırın</a>."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
@ -4390,8 +4387,8 @@ msgid ""
msgstr ""
"Matrix sunucusu etki alanı <em>%(domain_name)s</em> olarak ayarlandı. "
"Kullanıcı kimlikleri <em>@kullanıcıadı:%(domain_name)s</em> şeklinde "
"görünecek. İlk ayarlamadan sonra etki alanı adının değiştirilmesi şu anda "
"desteklenmiyor."
"görünecek. Etki alanı adını değiştirmek, uygulamanın kaldırılmasını ve "
"yeniden yüklenmesini gerektirir; bu da uygulamanın verilerini siler."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4434,10 +4431,8 @@ msgid "Unlimited"
msgstr "Sınırsız"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:78
#, fuzzy
#| msgid "Feed generator"
msgid "Federation"
msgstr "Bildirim oluşturucu"
msgstr "Federasyon"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:81
#, python-format
@ -4448,6 +4443,13 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse, internet'teki diğer Matrix sunucularıyla çalışacak şekilde "
"yapılandırılmıştır. Bu, %(box_name)s kullanıcılarının başka bir yerde "
"barındırılan odalara katılmasını ve diğer sunuculardaki Matrix "
"kullanıcılarının burada barındırılan odalara katılmasını sağlar. Eğer "
"federasyonla ilgili sorunlarla karşılaşırsanız, <a "
"href=\"%(tester_url)s#%(domain_name)s\">federasyon deneyici aracını</a> "
"deneyin."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -7307,18 +7309,14 @@ msgstr ""
"href=\"{users_url}\">herhangi bir kullanıcı</a> tarafından erişilebilir."
#: plinth/modules/rssbridge/__init__.py:28
#, fuzzy, python-brace-format
#| msgid ""
#| "You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
#| "href=\"{ttrss_url}\">Tiny Tiny RSS</a> to follow various websites. When "
#| "adding a feed, enable authentication and use your {box_name} credentials."
#, python-brace-format
msgid ""
"You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"Çeşitli web sitelerini takip etmek için <a href=\"{miniflux_url}\">Miniflux</"
"a> veya <a href=\"{ttrss_url}\">Tiny Tiny RSS</a> ile RSS-Bridge'i "
"a> veya <a href=\"{nextcloud_url}\">Nextcloud News</a> ile RSS-Bridge'i "
"kullanabilirsiniz. Bir bildirim eklerken, kimlik doğrulamayı etkinleştirin "
"ve {box_name} kimlik bilgilerinizi kullanın."

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-09-24 03:02+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-12 07:51+0000\n"
"Last-Translator: Максим Горпиніч <gorpinicmaksim0@gmail.com>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/freedombox/"
"freedombox/uk/>\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Weblate 5.14-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: plinth/config.py:103
#, python-brace-format
@ -3924,7 +3924,19 @@ msgstr "Входить проста кімната для відеоконфер
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr "Для використання Janus потрібен <a href=\"{coturn_url}\">Coturn</a>."
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Примітка:</strong> Ця програма отримує часті оновлення функцій. Її "
"можна встановити, лише якщо в програмі <a href=\"{upgrades_url}\">Оновлення "
"програмного забезпечення</a> увімкнено часті оновлення функцій."
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr "Janus"
@ -3940,7 +3952,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr "Веб-конференція"
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4275,17 +4287,6 @@ msgstr ""
"Встановіть програму <a href=\"{coturn_url}\">Coturn</a> або налаштуйте "
"зовнішній сервер."
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
"<strong>Примітка:</strong> Ця програма отримує часті оновлення функцій. Її "
"можна встановити, лише якщо в програмі <a href=\"{upgrades_url}\">Оновлення "
"програмного забезпечення</a> увімкнено часті оновлення функцій."
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Матричний синапс"
@ -4385,20 +4386,16 @@ msgstr ""
"щонайменше один домен для використання Matrix Synapse."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
"requires uninstalling and reinstalling the app which will wipe app's data."
msgstr ""
"Домен сервера Matrix встановлюється на <em>%(domain_name)s</em>. "
"Ідентифікатори користувачів будуть виглядати як <em>@ім'я користувача:"
"%(domain_name)s</em>. Зміна доменного імені після початкового налаштування "
"наразі не підтримується."
"Домен сервера Matrix встановлений на <em>%(domain_name)s</em>. "
"Ідентифікатори користувача будуть схожі на <em>@username:%(domain_name)s</"
"em>. Зміна доменного ім'я вимагає видалення та повторної установки програми, "
"яка витримає дані додатка."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4441,10 +4438,8 @@ msgid "Unlimited"
msgstr "Необмежено"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:78
#, fuzzy
#| msgid "Feed generator"
msgid "Federation"
msgstr "Генератор корму"
msgstr "Федерація"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:81
#, python-format
@ -4455,6 +4450,12 @@ msgid ""
"hosted here. If you face problems with federation, try the <a "
"href=\"%(tester_url)s#%(domain_name)s\"> federation tester tool</a>."
msgstr ""
"Matrix Synapse налаштований для роботи з іншими серверами Matrix в "
"Інтернеті. Це дозволяє користувачам %(box_name)s брати участь у чатах, що "
"розміщені в інших місцях, а користувачам Matrix на інших серверах — брати "
"участь у чатах, розміщених тут. Якщо у вас виникли проблеми з федерацією, "
"спробуйте <a href=\"%(tester_url)s#%(domain_name)s\">інструмент для "
"тестування федерації</a>."
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:99
#, python-format
@ -7311,20 +7312,16 @@ msgstr ""
"\">будь-якого користувача</a>, який належить до групи feed-reader."
#: plinth/modules/rssbridge/__init__.py:28
#, fuzzy, python-brace-format
#| msgid ""
#| "You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
#| "href=\"{ttrss_url}\">Tiny Tiny RSS</a> to follow various websites. When "
#| "adding a feed, enable authentication and use your {box_name} credentials."
#, python-brace-format
msgid ""
"You can use RSS-Bridge with <a href=\"{miniflux_url}\">Miniflux</a> or <a "
"href=\"{nextcloud_url}\">Nextcloud News</a> to follow various websites. When "
"adding a feed, enable authentication and use your {box_name} credentials."
msgstr ""
"Ви можете використовувати RSS-Bridge із <a href=\"{miniflux_url}\">Miniflux</"
"a> або <a href=\"{ttrss_url}\">Tiny Tiny RSS</a>, щоб стежити за різними веб-"
"сайтами. Додаючи канал, увімкніть автентифікацію та використовуйте свої "
"облікові дані {box_name}."
"Ви можете використовувати RSS-Bridge з <a href=\"{miniflux_url}\">Miniflux</"
"a> або <a>a href=\"{nextcloud_url}: &gt;Nextcloud News</a> для перегляду "
"різних веб-сайтів. Під час додавання фід, дозвольте аутентифікації та "
"використовуйте свої акредитації {box_name}."
#: plinth/modules/rssbridge/__init__.py:49
msgid "Read and subscribe to news feeds"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2021-07-28 08:34+0000\n"
"Last-Translator: bruh <quangtrung02hn16@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/freedombox/"
@ -3836,7 +3836,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3854,7 +3863,7 @@ msgstr "Máy chủ web"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4154,14 +4163,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Plinth\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"PO-Revision-Date: 2025-09-24 03:02+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-11-12 07:51+0000\n"
"Last-Translator: 大王叫我来巡山 "
"<hamburger2048@users.noreply.hosted.weblate.org>\n"
"Language-Team: Chinese (Simplified Han script) <https://hosted.weblate.org/"
@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.14-dev\n"
"X-Generator: Weblate 5.15-dev\n"
#: plinth/config.py:103
#, python-brace-format
@ -3640,7 +3640,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3656,7 +3665,7 @@ msgstr "WebRTC"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -3952,14 +3961,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr "Matrix Synapse"
@ -4038,18 +4039,15 @@ msgid ""
msgstr ""
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:20
#, fuzzy, python-format
#| msgid ""
#| "The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs "
#| "will look like <em>@username:%(domain_name)s</em>. Changing the domain "
#| "name after the initial setup is currently not supported."
#, python-format
msgid ""
"The Matrix server domain is set to <em>%(domain_name)s</em>. User IDs will "
"look like <em>@username:%(domain_name)s</em>. Changing the domain name "
"requires uninstalling and reinstalling the app which will wipe app's data."
msgstr ""
"Matrix 服务器域名已设置为 <em>%(domain_name)s <em>。用户 ID 看起来像是这样 "
"<em>@username:%(domain_name)s</em>。尚不支持在初始设置后更改域名。</em></em>"
"<em>@username:%(domain_name)s</em>。更改域名需要卸载并重新安装该应用,这会抹"
"去应用的数据。</em></em>"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:28
msgid ""
@ -4088,10 +4086,8 @@ msgid "Unlimited"
msgstr ""
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:78
#, fuzzy
#| msgid "Conversations"
msgid "Federation"
msgstr "Conversations"
msgstr "联邦"
#: plinth/modules/matrixsynapse/templates/matrix-synapse.html:81
#, python-format

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-11 01:20+0000\n"
"POT-Creation-Date: 2025-11-25 01:21+0000\n"
"PO-Revision-Date: 2025-02-07 12:01+0000\n"
"Last-Translator: pesder <j_h_liau@yahoo.com.tw>\n"
"Language-Team: Chinese (Traditional Han script) <https://hosted.weblate.org/"
@ -3735,7 +3735,16 @@ msgstr ""
msgid "<a href=\"{coturn_url}\">Coturn</a> is required to use Janus."
msgstr ""
#: plinth/modules/janus/__init__.py:42
#: plinth/modules/janus/__init__.py:29
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/janus/__init__.py:47
msgid "Janus"
msgstr ""
@ -3753,7 +3762,7 @@ msgstr "網頁伺服器"
msgid "Web conference"
msgstr ""
#: plinth/modules/janus/templates/janus_video_room.html:205
#: plinth/modules/janus/templates/janus_video_room.html:204
#: plinth/modules/jsxc/templates/jsxc_launch.html:117
#: plinth/templates/base.html:272
msgid "JavaScript license information"
@ -4053,14 +4062,6 @@ msgid ""
"<a href={coturn_url}>Coturn</a> app or configure an external server."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:38
#, python-brace-format
msgid ""
"<strong>Note:</strong> This app receives frequent feature updates. It can "
"only be installed if frequent feature updates is enabled in the <a "
"href=\"{upgrades_url}\">Software Update</a> app."
msgstr ""
#: plinth/modules/matrixsynapse/__init__.py:59
msgid "Matrix Synapse"
msgstr ""

View File

@ -188,3 +188,93 @@ class CommonErrorMiddleware(MiddlewareMixin):
breadcrumbs = views.get_breadcrumbs(request)
parent_index = 1 if len(breadcrumbs) > 1 else 0
return list(breadcrumbs.keys())[parent_index]
class CSPDict(dict):
"""A dictionary to store Content Security Policy.
And return a full value of the HTTP header.
"""
def get_header_value(self) -> str:
"""Return the string header value for the policy stored."""
return ' '.join([f'{key} {value};' for key, value in self.items()])
CONTENT_SECURITY_POLICY = CSPDict({
# @fonts are allowed only from FreedomBox itself.
'font-src': "'self'",
# <frame>/<iframe> sources are disabled.
'frame-src': "'none'",
# <img> sources are allowed only from FreedomBox itself. Allow
# data: URLs for SVGs in CSS.
'img-src': "'self' data:",
# Manifest file is not allowed as there is none yet.
'manifest-src': "'none'",
# <audio>, <video>, <track> tags are not allowed yet.
'media-src': "'none'",
# <object>, <embed>, <applet> tags are not allowed yet. No plugins
# types are alllowed since object-src is 'none'.
'object-src': "'none'",
# Allow JS from FreedomBox itself (no inline and attribute
# scripts).
'script-src': "'self'",
# Allow inline CSS and CSS files from Freedombox itself.
'style-src': "'self'",
# Web worker sources are allowed only from FreedomBox itself (for
# JSXC).
'worker-src': "'self'",
# All other fetch sources including Ajax are not allowed from
# FreedomBox itself.
'default-src': "'self'",
# <base> tag is not allowed.
'base-uri': "'none'",
# Enable strict sandboxing enabled with some exceptions:
# - Allow running Javascript.
# - Allow popups as sometimes we use <a target=_blank>
# - Allow popups to have different sandbox requirements as we
# launch apps' web clients.
# - Allow forms to support configuration forms.
# - Allow policies to treat same origin differently from other
# - origins
# - Allow downloads such as backup tarballs.
'sandbox': 'allow-scripts allow-popups '
'allow-popups-to-escape-sandbox allow-forms '
'allow-same-origin allow-downloads',
# Form action should be to FreedomBox itself.
'form-action': "'self'",
# This interface may be not embedded in <frame>, <iframe>, etc.
# tags.
'frame-ancestors': "'none'",
})
class CommonHeadersMiddleware:
def __init__(self, get_response):
"""Initialize the middleware object."""
self.get_response = get_response
def __call__(self, request):
"""Add common security middleware."""
# Disable sending Referer (sic) header from FreedomBox web interface to
# external websites. This improves privacy by not disclosing FreedomBox
# domains/URLs to external domains. Apps such as blogs which want to
# popularize themselves with referrer header may still do so.
response = self.get_response(request)
if not response.get('Referrer-Policy'):
response['Referrer-Policy'] = 'same-origin'
# Disable browser guessing of MIME types. FreedoBox already sets good
# content types for all the common file types.
if not response.get('X-Content-Type-Options'):
response['X-Content-Type-Options'] = 'nosniff'
csp = ' '.join([
f'{key} {value};'
for key, value in CONTENT_SECURITY_POLICY.items()
])
if not response.get('Content-Security-Policy'):
response['Content-Security-Policy'] = csp
return response

View File

@ -5,6 +5,7 @@ GnuDIP client for updating Dynamic DNS records.
import hashlib
import logging
import socket
from html.parser import HTMLParser
import requests
@ -45,18 +46,43 @@ def _check_required_keys(dictionary: dict[str, str], keys: list[str]) -> None:
f"Missing required keys in response: {', '.join(missing_keys)}")
def _request_get_ipv4(*args, **kwargs):
"""Make a IPv4-only request.
XXX: This monkey-patches socket.getaddrinfo which may causes issues when
running multiple threads. With urllib3 >= 2.4 (Trixie has 2.3), it is
possible to implement more cleanly. Use a session for requests library. In
the session add custom adapter for https:. In the adapter, override
creation of pool manager, and pass socket_family parameter.
"""
original = socket.getaddrinfo
def getaddrinfo_ipv4(*args, **kwargs):
return original(args[0], args[1], socket.AF_INET, *args[3:], **kwargs)
socket.getaddrinfo = getaddrinfo_ipv4
try:
return requests.get(*args, **kwargs)
finally:
socket.getaddrinfo = original
def update(server: str, domain: str, username: str,
password: str) -> tuple[bool, str | None]:
"""Update Dynamic DNS record using GnuDIP protocol.
Protocol documentation:
https://gnudip2.sourceforge.net/gnudip-www/latest/gnudip/html/protocol.html
GnuDIP at least as deployed on the FreedomBox foundation servers does not
support IPv6 (it does have any code to update AAAA records). So, make a
request only using IPv4 stack.
"""
domain = domain.removeprefix(username + '.')
password_digest = hashlib.md5(password.encode()).hexdigest()
http_server = f'https://{server}/gnudip/cgi-bin/gdipupdt.cgi'
response = requests.get(http_server)
response = _request_get_ipv4(http_server)
salt_response = _extract_content_from_meta_tags(response.text)
_check_required_keys(salt_response, ['salt', 'time', 'sign'])
@ -74,7 +100,7 @@ def update(server: str, domain: str, username: str,
'pass': password_digest,
'reqc': '2'
}
update_response = requests.get(http_server, params=query_params)
update_response = _request_get_ipv4(http_server, params=query_params)
update_result = _extract_content_from_meta_tags(update_response.text)
_check_required_keys(update_result, ['retc'])

View File

@ -25,6 +25,11 @@ _description = [
format_lazy(
_('<a href="{coturn_url}">Coturn</a> is required to '
'use Janus.'), coturn_url=reverse_lazy('coturn:index')),
format_lazy(
_('<strong>Note:</strong> This app receives frequent feature updates. '
'It can only be installed if frequent feature updates is enabled in '
'the <a href="{upgrades_url}">Software Update</a> app.'),
upgrades_url=reverse_lazy('upgrades:index')),
]
@ -56,9 +61,9 @@ class JanusApp(app_module.App):
self.add(shortcut)
packages = Packages('packages-janus', [
'janus', 'libjs-jquery', 'libjs-bootbox', 'libjs-bootstrap',
'libjs-bootswatch', 'libjs-janus-gateway', 'libjs-jquery-blockui',
'libjs-spin.js', 'libjs-toastr', 'libjs-webrtc-adapter'
'janus', 'libjs-jquery', 'libjs-bootbox', 'libjs-bootstrap5',
'libjs-janus-gateway', 'libjs-jquery-blockui', 'libjs-toastr',
'libjs-webrtc-adapter', 'node-popper2'
])
self.add(packages)

View File

@ -4,7 +4,7 @@
# This file based on example code from Janus Demos which is licensed as
# follows.
#
# 2014-2022 Meetecho
# 2014-2025 Meetecho
#
# GPL-3 with OpenSSL exception
# If you modify this Program, or any covered work,
@ -18,10 +18,36 @@
# as well as that of the covered work.
*/
/* Default style removed in bootstrap 4 */
.btn-default {
--bs-btn-color: #333;
--bs-btn-bg: #fff;
--bs-btn-border-color: #ccc;
--bs-btn-hover-color: #333;
--bs-btn-hover-bg: #e6e6e6;
--bs-btn-hover-border-color: #adadad;
--bs-btn-focus-shadow-rgb: 192, 192, 192;
--bs-btn-active-color: #333;
--bs-btn-active-bg: #e6e6e6;
--bs-btn-active-border-color: #adadad;
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
--bs-btn-disabled-color: #333;
--bs-btn-disabled-bg: #e6e6e6;
--bs-btn-disabled-border-color: #adadad;
}
.footer {
display: none;
}
.hide {
display: none !important;
}
.z-2 {
z-index: 2000;
}
.rounded {
border-radius: 5px;
}
@ -35,11 +61,35 @@
position: relative;
}
.top-left {
position: absolute;
top: 0px;
left: 0px;
}
.top-right {
position: absolute;
top: 0px;
right: 0px;
}
.bottom-left {
position: absolute;
bottom: 0px;
left: 0px;
}
.bottom-right {
position: absolute;
bottom: 0px;
right: 0px;
}
.navbar-brand {
margin-left: 0px !important;
}
.navbar-default {
.navbar {
-webkit-box-shadow: 0px 3px 5px rgba(100, 100, 100, 0.49);
-moz-box-shadow: 0px 3px 5px rgba(100, 100, 100, 0.49);
box-shadow: 0px 3px 5px rgba(100, 100, 100, 0.49);
@ -49,23 +99,11 @@
padding-left: 40px;
}
.margin-sm {
margin: 5px !important;
}
.margin-md {
margin: 10px !important;
}
.margin-xl {
margin: 20px !important;
}
.margin-bottom-sm {
margin-bottom: 5px !important;
}
.margin-bottom-md {
margin-bottom: 10px !important;
}
.margin-bottom-xl {
margin-bottom: 20px !important;
.btn-group-xs > .btn, .btn-xs {
padding: 1px 5px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
.divider {
@ -87,6 +125,7 @@ div.no-video-container {
width: 100%;
height: 240px;
text-align: center;
padding-top: 5rem !important;
}
.no-video-text {
@ -121,6 +160,11 @@ pre {
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
background-color: #f5f5f5;
}
.bg-gray {
background-color: #f5f5f5;
}
.januscon {
@ -164,7 +208,3 @@ pre {
.simulcast-button-group {
width: 100%;
}
.simulcast-button {
width: 33%;
}

View File

@ -20,7 +20,7 @@
# This file based on example code from Janus Demos which is licensed as
# follows.
#
# 2014-2022 Meetecho
# 2014-2025 Meetecho
#
# GPL-3 with OpenSSL exception
# If you modify this Program, or any covered work,
@ -50,12 +50,16 @@ var mypvtid = null;
var remoteFeed = null;
var feeds = {}, feedStreams = {}, subStreams = {}, slots = {}, mids = {}, subscriptions = {};
var localTracks = {}, localVideos = 0, remoteTracks = {};
var bitrateTimer = [], simulcastStarted = {};
var bitrateTimer = [], simulcastStarted = {}, svcStarted = {};
var doSimulcast = (getQueryStringValue("simulcast") === "yes" || getQueryStringValue("simulcast") === "true");
var doSvc = getQueryStringValue("svc");
if(doSvc === "")
doSvc = null;
var acodec = (getQueryStringValue("acodec") !== "" ? getQueryStringValue("acodec") : null);
var vcodec = (getQueryStringValue("vcodec") !== "" ? getQueryStringValue("vcodec") : null);
var subscriber_mode = (getQueryStringValue("subscriber-mode") === "yes" || getQueryStringValue("subscriber-mode") === "true");
var use_msid = (getQueryStringValue("msid") === "yes" || getQueryStringValue("msid") === "true");
$(document).ready(function() {
// Initialize the library (all console debuggers enabled)
@ -87,8 +91,8 @@ $(document).ready(function() {
Janus.log("Plugin attached! (" + sfutest.getPlugin() + ", id=" + sfutest.getId() + ")");
Janus.log(" -- This is a publisher/manager");
// Prepare the username registration
$('#videojoin').removeClass('hide').show();
$('#registernow').removeClass('hide').show();
$('#videojoin').removeClass('hide');
$('#registernow').removeClass('hide');
$('#register').click(registerUsername);
$('#username').focus();
$('#start').removeAttr('disabled').html("Stop")
@ -117,16 +121,17 @@ $(document).ready(function() {
return;
$('#publish').remove();
// This controls allows us to override the global room bitrate cap
$('#bitrate').parent().parent().removeClass('hide').show();
$('#bitrate').parent().parent().removeClass('hide');
$('#bitrate a').click(function() {
var id = $(this).attr("id");
var bitrate = parseInt(id)*1000;
$('.dropdown-toggle').dropdown('hide');
let id = $(this).attr("id");
let bitrate = parseInt(id)*1000;
if(bitrate === 0) {
Janus.log("Not limiting bandwidth via REMB");
} else {
Janus.log("Capping bandwidth to " + bitrate + " via REMB");
}
$('#bitrateset').html($(this).html() + '<span class="caret"></span>').parent().removeClass('open');
$('#bitrateset').text($(this).text()).parent().removeClass('open');
sfutest.send({ message: { request: "configure", bitrate: bitrate }});
return false;
});
@ -137,7 +142,7 @@ $(document).ready(function() {
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message (publisher) :::", msg);
var event = msg["videoroom"];
let event = msg["videoroom"];
Janus.debug("Event: " + event);
if(event != undefined && event != null) {
if(event === "joined") {
@ -146,29 +151,35 @@ $(document).ready(function() {
mypvtid = msg["private_id"];
Janus.log("Successfully joined room " + msg["room"] + " with ID " + myid);
if(subscriber_mode) {
$('#videojoin').hide();
$('#videos').removeClass('hide').show();
$('#videojoin').addClass('hide');
$('#videos').removeClass('hide');
} else {
publishOwnFeed(true);
}
// Any new feed to attach to?
if(msg["publishers"]) {
var list = msg["publishers"];
let list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:", list);
var sources = null;
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
var streams = list[f]["streams"];
for(var i in streams) {
var stream = streams[i];
let sources = null;
for(let f in list) {
if(list[f]["dummy"])
continue;
let id = list[f]["id"];
let display = list[f]["display"];
let streams = list[f]["streams"];
for(let i in streams) {
let stream = streams[i];
stream["id"] = id;
stream["display"] = display;
}
let slot = feedStreams[id] ? feedStreams[id].slot : null;
let remoteVideos = feedStreams[id] ? feedStreams[id].remoteVideos : 0;
feedStreams[id] = {
id: id,
display: display,
streams: streams
streams: streams,
slot: slot,
remoteVideos: remoteVideos
}
Janus.debug(" >> [" + id + "] " + display + ":", streams);
if(!sources)
@ -187,9 +198,9 @@ $(document).ready(function() {
} else if(event === "event") {
// Any info on our streams or a new feed to attach to?
if(msg["streams"]) {
var streams = msg["streams"];
for(var i in streams) {
var stream = streams[i];
let streams = msg["streams"];
for(let i in streams) {
let stream = streams[i];
stream["id"] = myid;
stream["display"] = myusername;
}
@ -199,22 +210,28 @@ $(document).ready(function() {
streams: streams
}
} else if(msg["publishers"]) {
var list = msg["publishers"];
let list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:", list);
var sources = null;
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
var streams = list[f]["streams"];
for(var i in streams) {
var stream = streams[i];
let sources = null;
for(let f in list) {
if(list[f]["dummy"])
continue;
let id = list[f]["id"];
let display = list[f]["display"];
let streams = list[f]["streams"];
for(let i in streams) {
let stream = streams[i];
stream["id"] = id;
stream["display"] = display;
}
let slot = feedStreams[id] ? feedStreams[id].slot : null;
let remoteVideos = feedStreams[id] ? feedStreams[id].remoteVideos : 0;
feedStreams[id] = {
id: id,
display: display,
streams: streams
streams: streams,
slot: slot,
remoteVideos: remoteVideos
}
Janus.debug(" >> [" + id + "] " + display + ":", streams);
if(!sources)
@ -225,12 +242,12 @@ $(document).ready(function() {
subscribeTo(sources);
} else if(msg["leaving"]) {
// One of the publishers has gone away?
var leaving = msg["leaving"];
let leaving = msg["leaving"];
Janus.log("Publisher left: " + leaving);
unsubscribeFrom(leaving);
} else if(msg["unpublished"]) {
// One of the publishers has unpublished?
var unpublished = msg["unpublished"];
let unpublished = msg["unpublished"];
Janus.log("Publisher left: " + unpublished);
if(unpublished === 'ok') {
// That's us
@ -258,21 +275,21 @@ $(document).ready(function() {
sfutest.handleRemoteJsep({ jsep: jsep });
// Check if any of the media we wanted to publish has
// been rejected (e.g., wrong or unsupported codec)
var audio = msg["audio_codec"];
let audio = msg["audio_codec"];
if(mystream && mystream.getAudioTracks() && mystream.getAudioTracks().length > 0 && !audio) {
// Audio has been rejected
toastr.warning("Our audio stream has been rejected, viewers won't hear us");
}
var video = msg["video_codec"];
let video = msg["video_codec"];
if(mystream && mystream.getVideoTracks() && mystream.getVideoTracks().length > 0 && !video) {
// Video has been rejected
toastr.warning("Our video stream has been rejected, viewers won't see us");
// Hide the webcam video
$('#myvideo').hide();
$('#videolocal').append(
$('#myvideo').addClass('hide');
$('#videolocal').prepend(
'<div class="no-video-container">' +
'<span class="no-video-text-sm">Video rejected, no webcam</span>' +
'</div>');
'</div>');
}
}
},
@ -280,18 +297,19 @@ $(document).ready(function() {
Janus.debug(" ::: Got a local track event :::");
Janus.debug("Local track " + (on ? "added" : "removed") + ":", track);
// We use the track ID as name of the element, but it may contain invalid characters
var trackId = track.id.replace(/[{}]/g, "");
let trackId = track.id.replace(/[{}]/g, "");
if(!on) {
// Track removed, get rid of the stream and the rendering
var stream = localTracks[trackId];
let stream = localTracks[trackId];
if(stream) {
try {
var tracks = stream.getTracks();
for(var i in tracks) {
var mst = tracks[i];
let tracks = stream.getTracks();
for(let i in tracks) {
let mst = tracks[i];
if(mst)
mst.stop();
}
// eslint-disable-next-line no-unused-vars
} catch(e) {}
}
if(track.kind === "video") {
@ -300,10 +318,10 @@ $(document).ready(function() {
if(localVideos === 0) {
// No video, at least for now: show a placeholder
if($('#videolocal .no-video-container').length === 0) {
$('#videolocal').append(
$('#videolocal').prepend(
'<div class="no-video-container">' +
'<span class="no-video-text">No webcam available</span>' +
'</div>');
'</div>');
}
}
}
@ -311,12 +329,12 @@ $(document).ready(function() {
return;
}
// If we're here, a new track was added
var stream = localTracks[trackId];
let stream = localTracks[trackId];
if(stream) {
// We've been here already
return;
}
$('#videos').removeClass('hide').show();
$('#videos').removeClass('hide');
if($('#mute').length === 0) {
// Add a 'mute' button
$('#videolocal').append('<button class="btn btn-warning btn-xs mute-button" id="mute">Mute</button>');
@ -330,23 +348,22 @@ $(document).ready(function() {
if(localVideos === 0) {
// No video, at least for now: show a placeholder
if($('#videolocal .no-video-container').length === 0) {
$('#videolocal').append(
$('#videolocal').prepend(
'<div class="no-video-container">' +
'<span class="no-video-text">No webcam available</span>' +
'</div>');
'</div>');
}
}
} else {
// New video track: create a stream out of it
localVideos++;
$('#videolocal .no-video-container').remove();
stream = new MediaStream();
stream.addTrack(track.clone());
let stream = new MediaStream([track]);
localTracks[trackId] = stream;
Janus.log("Created local stream:", stream);
Janus.log(stream.getTracks());
Janus.log(stream.getVideoTracks());
$('#videolocal').append('<video class="rounded centered" id="myvideo' + trackId + '" width=100% autoplay playsinline muted="muted"/>');
$('#videolocal').prepend('<video class="rounded centered" id="myvideo' + trackId + '" width=100% autoplay playsinline muted="muted"/>');
Janus.attachMediaStream($('#myvideo' + trackId).get(0), stream);
}
if(sfutest.webrtcStuff.pc.iceConnectionState !== "completed" &&
@ -361,6 +378,7 @@ $(document).ready(function() {
});
}
},
// eslint-disable-next-line no-unused-vars
onremotetrack: function(track, mid, on) {
// The publisher stream is sendonly, we don't expect anything here
},
@ -392,8 +410,9 @@ $(document).ready(function() {
}});
});
// eslint-disable-next-line no-unused-vars
function checkEnter(field, event) {
var theCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
let theCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
if(theCode == 13) {
registerUsername();
return false;
@ -411,10 +430,10 @@ function registerUsername() {
// Try a registration
$('#username').attr('disabled', true);
$('#register').attr('disabled', true).unbind('click');
var username = $('#username').val();
let username = $('#username').val();
if(username === "") {
$('#you')
.removeClass().addClass('label label-warning')
.removeClass().addClass('badge bg-warning')
.html("Insert your display name (e.g., pippo)");
$('#username').removeAttr('disabled');
$('#register').removeAttr('disabled').click(registerUsername);
@ -422,13 +441,13 @@ function registerUsername() {
}
if(/[^a-zA-Z0-9]/.test(username)) {
$('#you')
.removeClass().addClass('label label-warning')
.removeClass().addClass('badge bg-warning')
.html('Input is not alphanumeric');
$('#username').removeAttr('disabled').val("");
$('#register').removeAttr('disabled').click(registerUsername);
return;
}
var register = {
let register = {
request: "join",
room: myroom,
ptype: "publisher",
@ -442,23 +461,32 @@ function registerUsername() {
function publishOwnFeed(useAudio) {
// Publish our stream
$('#publish').attr('disabled', true).unbind('click');
// We want sendonly audio and video (uncomment the data track
// too if you want to publish via datachannels as well)
let tracks = [];
if(useAudio)
tracks.push({ type: 'audio', capture: true, recv: false });
tracks.push({ type: 'video', capture: true, recv: false,
// We may need to enable simulcast or SVC on the video track
simulcast: doSimulcast,
// We only support SVC for VP9 and (still WIP) AV1
svc: ((vcodec === 'vp9' || vcodec === 'av1') && doSvc) ? doSvc : null
});
//~ tracks.push({ type: 'data' });
sfutest.createOffer(
{
// Add data:true here if you want to publish datachannels as well
media: { audioRecv: false, videoRecv: false, audioSend: useAudio, videoSend: true }, // Publishers are sendonly
// If you want to test simulcasting (Chrome and Firefox only), then
// pass a ?simulcast=true when opening this demo page: it will turn
// the following 'simulcast' property to pass to janus.js to true
simulcast: doSimulcast,
tracks: tracks,
success: function(jsep) {
Janus.debug("Got publisher SDP!");
Janus.debug(jsep);
var publish = { request: "configure", audio: useAudio, video: true };
let publish = { request: "configure", audio: useAudio, video: true };
// You can force a specific codec to use when publishing by using the
// audiocodec and videocodec properties, for instance:
// publish["audiocodec"] = "opus"
// publish["audiocodec"] = "opus"
// to force Opus as the audio codec to use, or:
// publish["videocodec"] = "vp9"
// publish["videocodec"] = "vp9"
// to force VP9 as the videocodec to use. In both case, though, forcing
// a codec will only work if: (1) the codec is actually in the SDP (and
// so the browser supports it), and (2) the codec is in the list of
@ -483,7 +511,7 @@ function publishOwnFeed(useAudio) {
}
function toggleMute() {
var muted = sfutest.isAudioMuted();
let muted = sfutest.isAudioMuted();
Janus.log((muted ? "Unmuting" : "Muting") + " local stream...");
if(muted)
sfutest.unmuteAudio();
@ -496,7 +524,7 @@ function toggleMute() {
function unpublishOwnFeed() {
// Unpublish our stream
$('#unpublish').attr('disabled', true).unbind('click');
var unpublish = { request: "unpublish" };
let unpublish = { request: "unpublish" };
sfutest.send({ message: unpublish });
}
@ -514,21 +542,28 @@ function subscribeTo(sources) {
if(remoteFeed) {
// Prepare the streams to subscribe to, as an array: we have the list of
// streams the feeds are publishing, so we can choose what to pick or skip
var subscription = [];
for(var s in sources) {
var streams = sources[s];
for(var i in streams) {
var stream = streams[i];
let added = null, removed = null;
for(let s in sources) {
let streams = sources[s];
for(let i in streams) {
let stream = streams[i];
// If the publisher is VP8/VP9 and this is an older Safari, let's avoid video
if(stream.type === "video" && Janus.webRTCAdapter.browserDetails.browser === "safari" &&
(stream.codec === "vp9" || (stream.codec === "vp8" && !Janus.safariVp8))) {
((stream.codec === "vp9" && !Janus.safariVp9) || (stream.codec === "vp8" && !Janus.safariVp8))) {
toastr.warning("Publisher is using " + stream.codec.toUpperCase +
", but Safari doesn't support it: disabling video stream #" + stream.mindex);
continue;
}
if(stream.disabled) {
Janus.log("Disabled stream:", stream);
// TODO Skipping for now, we should unsubscribe
// Unsubscribe
if(!removed)
removed = [];
removed.push({
feed: stream.id, // This is mandatory
mid: stream.mid // This is optional (all streams, if missing)
});
delete subscriptions[stream.id][stream.mid];
continue;
}
if(subscriptions[stream.id] && subscriptions[stream.id][stream.mid]) {
@ -537,35 +572,40 @@ function subscribeTo(sources) {
}
// Find an empty slot in the UI for each new source
if(!feedStreams[stream.id].slot) {
var slot;
for(var i=1;i<6;i++) {
let slot;
for(let i=1;i<6;i++) {
if(!feeds[i]) {
slot = i;
feeds[slot] = stream.id;
feedStreams[stream.id].slot = slot;
feedStreams[stream.id].remoteVideos = 0;
$('#remote' + slot).removeClass('hide').html(escapeXmlTags(stream.display)).show();
$('#remote' + slot).removeClass('hide').html(escapeXmlTags(stream.display)).removeClass('hide');
break;
}
}
}
subscription.push({
// Subscribe
if(!added)
added = [];
added.push({
feed: stream.id, // This is mandatory
mid: stream.mid // This is optional (all streams, if missing)
mid: stream.mid // This is optional (all streams, if missing)
});
if(!subscriptions[stream.id])
subscriptions[stream.id] = {};
subscriptions[stream.id][stream.mid] = true;
}
}
if(subscription.length === 0) {
if((!added || added.length === 0) && (!removed || removed.length === 0)) {
// Nothing to do
return;
}
remoteFeed.send({ message: {
request: "subscribe",
streams: subscription
}});
let update = { request: 'update' };
if(added)
update.subscribe = added;
if(removed)
update.unsubscribe = removed;
remoteFeed.send({ message: update });
// Nothing else we need to do
return;
}
@ -582,14 +622,14 @@ function subscribeTo(sources) {
Janus.log(" -- This is a multistream subscriber");
// Prepare the streams to subscribe to, as an array: we have the list of
// streams the feed is publishing, so we can choose what to pick or skip
var subscription = [];
for(var s in sources) {
var streams = sources[s];
for(var i in streams) {
var stream = streams[i];
let subscription = [];
for(let s in sources) {
let streams = sources[s];
for(let i in streams) {
let stream = streams[i];
// If the publisher is VP8/VP9 and this is an older Safari, let's avoid video
if(stream.type === "video" && Janus.webRTCAdapter.browserDetails.browser === "safari" &&
(stream.codec === "vp9" || (stream.codec === "vp8" && !Janus.safariVp8))) {
((stream.codec === "vp9" && !Janus.safariVp9) || (stream.codec === "vp8" && !Janus.safariVp8))) {
toastr.warning("Publisher is using " + stream.codec.toUpperCase +
", but Safari doesn't support it: disabling video stream #" + stream.mindex);
continue;
@ -606,21 +646,21 @@ function subscribeTo(sources) {
}
// Find an empty slot in the UI for each new source
if(!feedStreams[stream.id].slot) {
var slot;
for(var i=1;i<6;i++) {
let slot;
for(let i=1;i<6;i++) {
if(!feeds[i]) {
slot = i;
feeds[slot] = stream.id;
feedStreams[stream.id].slot = slot;
feedStreams[stream.id].remoteVideos = 0;
$('#remote' + slot).removeClass('hide').html(escapeXmlTags(stream.display)).show();
$('#remote' + slot).removeClass('hide').html(escapeXmlTags(stream.display)).removeClass('hide');
break;
}
}
}
subscription.push({
feed: stream.id, // This is mandatory
mid: stream.mid // This is optional (all streams, if missing)
mid: stream.mid // This is optional (all streams, if missing)
});
if(!subscriptions[stream.id])
subscriptions[stream.id] = {};
@ -628,11 +668,12 @@ function subscribeTo(sources) {
}
}
// We wait for the plugin to send us an offer
var subscribe = {
let subscribe = {
request: "join",
room: myroom,
ptype: "subscriber",
streams: subscription,
use_msid: use_msid,
private_id: mypvtid
};
remoteFeed.send({ message: subscribe });
@ -653,7 +694,7 @@ function subscribeTo(sources) {
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message (subscriber) :::", msg);
var event = msg["videoroom"];
let event = msg["videoroom"];
Janus.debug("Event: " + event);
if(msg["error"]) {
bootbox.alert(msg["error"]);
@ -664,21 +705,32 @@ function subscribeTo(sources) {
Janus.log("Successfully attached to feed in room " + msg["room"]);
} else if(event === "event") {
// Check if we got an event on a simulcast-related event from this publisher
var mid = msg["mid"];
var substream = msg["substream"];
var temporal = msg["temporal"];
let mid = msg["mid"];
let substream = msg["substream"];
let temporal = msg["temporal"];
if((substream !== null && substream !== undefined) || (temporal !== null && temporal !== undefined)) {
// Check which this feed this refers to
var sub = subStreams[mid];
var feed = feedStreams[sub.feed_id];
var slot = slots[mid];
let slot = slots[mid];
if(!simulcastStarted[slot]) {
simulcastStarted[slot] = true;
// Add some new buttons
addSimulcastButtons(slot, true);
addSimulcastSvcButtons(slot, true);
}
// We just received notice that there's been a switch, update the buttons
updateSimulcastButtons(slot, substream, temporal);
updateSimulcastSvcButtons(slot, substream, temporal);
}
// Or maybe SVC?
let spatial = msg["spatial_layer"];
temporal = msg["temporal_layer"];
if((spatial !== null && spatial !== undefined) || (temporal !== null && temporal !== undefined)) {
let slot = slots[mid];
if(!svcStarted[slot]) {
svcStarted[slot] = true;
// Add some new buttons
addSimulcastSvcButtons(slot, true);
}
// We just received notice that there's been a switch, update the buttons
updateSimulcastSvcButtons(slot, spatial, temporal);
}
} else {
// What has just happened?
@ -686,10 +738,10 @@ function subscribeTo(sources) {
}
if(msg["streams"]) {
// Update map of subscriptions by mid
for(var i in msg["streams"]) {
var mid = msg["streams"][i]["mid"];
for(let i in msg["streams"]) {
let mid = msg["streams"][i]["mid"];
subStreams[mid] = msg["streams"][i];
var feed = feedStreams[msg["streams"][i]["feed_id"]];
let feed = feedStreams[msg["streams"][i]["feed_id"]];
if(feed && feed.slot) {
slots[mid] = feed.slot;
mids[feed.slot] = mid;
@ -702,13 +754,17 @@ function subscribeTo(sources) {
remoteFeed.createAnswer(
{
jsep: jsep,
// Add data:true here if you want to subscribe to datachannels as well
// (obviously only works if the publisher offered them in the first place)
media: { audioSend: false, videoSend: false }, // We want recvonly audio/video
// We only specify data channels here, as this way in
// case they were offered we'll enable them. Since we
// don't mention audio or video tracks, we autoaccept them
// as recvonly (since we won't capture anything ourselves)
tracks: [
{ type: 'data' }
],
success: function(jsep) {
Janus.debug("Got SDP!");
Janus.debug(jsep);
var body = { request: "start", room: myroom };
let body = { request: "start", room: myroom };
remoteFeed.send({ message: body, jsep: jsep });
},
error: function(error) {
@ -718,16 +774,21 @@ function subscribeTo(sources) {
});
}
},
// eslint-disable-next-line no-unused-vars
onlocaltrack: function(track, on) {
// The subscriber stream is recvonly, we don't expect anything here
},
onremotetrack: function(track, mid, on) {
Janus.debug("Remote track (mid=" + mid + ") " + (on ? "added" : "removed") + ":", track);
onremotetrack: function(track, mid, on, metadata) {
Janus.debug(
"Remote track (mid=" + mid + ") " +
(on ? "added" : "removed") +
(metadata ? " (" + metadata.reason + ") ": "") + ":", track
);
// Which publisher are we getting on this mid?
var sub = subStreams[mid];
var feed = feedStreams[sub.feed_id];
let sub = subStreams[mid];
let feed = feedStreams[sub.feed_id];
Janus.debug(" >> This track is coming from feed " + sub.feed_id + ":", feed);
var slot = slots[mid];
let slot = slots[mid];
if(feed && !slot) {
slot = feed.slot;
slots[mid] = feed.slot;
@ -736,17 +797,6 @@ function subscribeTo(sources) {
Janus.debug(" >> mid " + mid + " is in slot " + slot);
if(!on) {
// Track removed, get rid of the stream and the rendering
var stream = remoteTracks[mid];
if(stream) {
try {
var tracks = stream.getTracks();
for(var i in tracks) {
var mst = tracks[i];
if(mst)
mst.stop();
}
} catch(e) {}
}
$('#remotevideo' + slot + '-' + mid).remove();
if(track.kind === "video" && feed) {
feed.remoteVideos--;
@ -766,16 +816,11 @@ function subscribeTo(sources) {
return;
}
// If we're here, a new track was added
if(feed.spinner) {
feed.spinner.stop();
feed.spinner = null;
}
if($('#remotevideo' + slot + '-' + mid).length > 0)
return;
if(track.kind === "audio") {
// New audio track: create a stream out of it, and use a hidden <audio> element
stream = new MediaStream();
stream.addTrack(track.clone());
let stream = new MediaStream([track]);
remoteTracks[mid] = stream;
Janus.log("Created remote audio stream:", stream);
$('#videoremote' + slot).append('<audio class="hide" id="remotevideo' + slot + '-' + mid + '" autoplay playsinline/>');
@ -793,45 +838,47 @@ function subscribeTo(sources) {
// New video track: create a stream out of it
feed.remoteVideos++;
$('#videoremote' + slot + ' .no-video-container').remove();
stream = new MediaStream();
stream.addTrack(track.clone());
let stream = new MediaStream([track]);
remoteTracks[mid] = stream;
Janus.log("Created remote video stream:", stream);
$('#videoremote' + slot).append('<video class="rounded centered" id="remotevideo' + slot + '-' + mid + '" width=100% autoplay playsinline/>');
$('#videoremote' + slot).append(
'<span class="label label-primary hide resolution-label" id="curres'+slot+'"></span>' +
'<span class="label label-info hide bitrate-label" id="curbitrate'+slot+'"></span>');
'<span class="badge bg-primary hide resolution-label" id="curres'+slot+'"></span>' +
'<span class="badge bg-info hide bitrate-label" id="curbitrate'+slot+'"></span>');
Janus.attachMediaStream($('#remotevideo' + slot + '-' + mid).get(0), stream);
// Note: we'll need this for additional videos too
if(!bitrateTimer[slot]) {
$('#curbitrate' + slot).removeClass('hide').show();
$('#curbitrate' + slot).removeClass('hide');
bitrateTimer[slot] = setInterval(function() {
if(!$("#videoremote" + slot + ' video').get(0))
return;
// Display updated bitrate, if supported
var bitrate = remoteFeed.getBitrate(mid);
let bitrate = remoteFeed.getBitrate(mid);
$('#curbitrate' + slot).text(bitrate);
// Check if the resolution changed too
var width = $("#videoremote" + slot + ' video').get(0).videoWidth;
var height = $("#videoremote" + slot + ' video').get(0).videoHeight;
if(width > 0 && height > 0)
$('#curres' + slot).removeClass('hide').text(width+'x'+height).show();
let width = $("#videoremote" + slot + ' video').get(0).videoWidth;
let height = $("#videoremote" + slot + ' video').get(0).videoHeight;
if(width > 0 && height > 0) {
let res = width + 'x' + height;
if(simulcastStarted[slot])
res += ' (simulcast)';
else if(svcStarted[slot])
res += ' (SVC)';
$('#curres' + slot).removeClass('hide').text(res).removeClass('hide');
}
}, 1000);
}
}
},
oncleanup: function() {
Janus.log(" ::: Got a cleanup notification (remote feed) :::");
for(var i=1;i<6;i++) {
$('#remotevideo'+i).remove();
$('#waitingvideo'+i).remove();
$('#novideo'+i).remove();
$('#curbitrate'+i).remove();
$('#curres'+i).remove();
for(let i=1;i<6;i++) {
$('#videoremote'+i).empty();
if(bitrateTimer[i])
clearInterval(bitrateTimer[i]);
bitrateTimer[i] = null;
feedStreams[i].simulcastStarted = false;
feedStreams[i].svcStarted = false;
feedStreams[i].remoteVideos = 0;
$('#simulcast'+i).remove();
}
@ -842,22 +889,23 @@ function subscribeTo(sources) {
function unsubscribeFrom(id) {
// Unsubscribe from this publisher
var feed = feedStreams[id];
let feed = feedStreams[id];
if(!feed)
return;
Janus.debug("Feed " + id + " (" + feed.display + ") has left the room, detaching");
if(bitrateTimer[feed.slot])
clearInterval(bitrateTimer[feed.slot]);
bitrateTimer[feed.slot] = null;
$('#remote' + feed.slot).empty().hide();
$('#remote' + feed.slot).empty().addClass('hide');
$('#videoremote' + feed.slot).empty();
delete simulcastStarted[feed.slot];
delete svcStarted[feed.slot];
$('#simulcast' + feed.slot).remove();
delete feeds[feed.slot];
feeds.slot = 0;
delete feedStreams[id];
// Send an unsubscribe request
var unsubscribe = {
let unsubscribe = {
request: "unsubscribe",
streams: [{ feed: id }]
};
@ -868,8 +916,8 @@ function unsubscribeFrom(id) {
// Helper to parse query string
function getQueryStringValue(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
name = name.replace(/[[]/, "\\[").replace(/[\]]/, "\\]");
let regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
@ -877,137 +925,161 @@ function getQueryStringValue(name) {
// Helper to escape XML tags
function escapeXmlTags(value) {
if(value) {
var escapedValue = value.replace(new RegExp('<', 'g'), '&lt');
let escapedValue = value.replace(new RegExp('<', 'g'), '&lt');
escapedValue = escapedValue.replace(new RegExp('>', 'g'), '&gt');
return escapedValue;
}
}
// Helpers to create Simulcast-related UI, if enabled
function addSimulcastButtons(feed, temporal) {
var index = feed;
// Helpers to create Simulcast- or SVC-related UI, if enabled
function addSimulcastSvcButtons(feed, temporal) {
let index = feed;
let simulcast = simulcastStarted[index];
let what = (simulcast ? 'simulcast' : 'SVC');
let layer = (simulcast ? 'substream' : 'layer');
$('#remote'+index).parent().append(
'<div id="simulcast'+index+'" class="btn-group-vertical btn-group-vertical-xs pull-right">' +
' <div class"row">' +
' <div class="btn-group btn-group-xs simulcast-button-group">' +
' <button id="sl'+index+'-2" type="button" class="btn btn-primary simulcast-button" data-toggle="tooltip" title="Switch to higher quality" style="width: 33%">SL 2</button>' +
' <button id="sl'+index+'-1" type="button" class="btn btn-primary simulcast-button" data-toggle="tooltip" title="Switch to normal quality" style="width: 33%">SL 1</button>' +
' <button id="sl'+index+'-0" type="button" class="btn btn-primary simulcast-button" data-toggle="tooltip" title="Switch to lower quality" style="width: 34%">SL 0</button>' +
' </div>' +
' </div>' +
' <div class"row">' +
' <div class="btn-group btn-group-xs hide simulcast-button-group">' +
' <button id="tl'+index+'-2" type="button" class="btn btn-primary simulcast-button" data-toggle="tooltip" title="Cap to temporal layer 2">TL 2</button>' +
' <button id="tl'+index+'-1" type="button" class="btn btn-primary simulcast-button" data-toggle="tooltip" title="Cap to temporal layer 1">TL 1</button>' +
' <button id="tl'+index+'-0" type="button" class="btn btn-primary simulcast-button" data-toggle="tooltip" title="Cap to temporal layer 0">TL 0</button>' +
' </div>' +
' </div>' +
'</div>'
'<div id="simulcast'+index+'" class="btn-group-vertical btn-group-xs top-right">' +
' <div class="btn-group btn-group-xs d-flex simulcast-button-group">' +
' <button id="sl'+index+'-2" type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Switch to higher quality">SL 2</button>' +
' <button id="sl'+index+'-1" type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Switch to normal quality">SL 1</button>' +
' <button id="sl'+index+'-0" type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Switch to lower quality">SL 0</button>' +
' </div>' +
' <div class="btn-group btn-group-xs d-flex hide simulcast-button-group">' +
' <button id="tl'+index+'-2" type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Cap to temporal layer 2">TL 2</button>' +
' <button id="tl'+index+'-1" type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Cap to temporal layer 1">TL 1</button>' +
' <button id="tl'+index+'-0" type="button" class="btn btn-primary" data-bs-toggle="tooltip" title="Cap to temporal layer 0">TL 0</button>' +
' </div>' +
'</div>'
);
if(simulcast && Janus.webRTCAdapter.browserDetails.browser !== "firefox") {
// Chromium-based browsers only have two temporal layers, when doing simulcast
$('#tl'+index+'-2').remove();
}
// Enable the simulcast selection buttons
$('#sl' + index + '-0').removeClass('btn-primary btn-success').addClass('btn-primary')
.unbind('click').click(function() {
var index = $(this).attr('id').split('sl')[1].split('-')[0];
toastr.info("Switching simulcast substream (mid=" + mids[index] + "), wait for it... (lower quality)", null, {timeOut: 2000});
let index = $(this).attr('id').split('sl')[1].split('-')[0];
toastr.info("Switching " + what + " " + layer + " (mid=" + mids[index] + "), wait for it... (lower quality)", null, {timeOut: 2000});
if(!$('#sl' + index + '-2').hasClass('btn-success'))
$('#sl' + index + '-2').removeClass('btn-primary btn-info').addClass('btn-primary');
if(!$('#sl' + index + '-1').hasClass('btn-success'))
$('#sl' + index + '-1').removeClass('btn-primary btn-info').addClass('btn-primary');
$('#sl' + index + '-0').removeClass('btn-primary btn-info btn-success').addClass('btn-info');
remoteFeed.send({ message: { request: "configure", mid: mids[index], substream: 0 }});
if(simulcastStarted[index])
remoteFeed.send({ message: { request: "configure", mid: mids[index], substream: 0 }});
else
remoteFeed.send({ message: { request: "configure", mid: mids[index], spatial_layer: 0 }});
});
$('#sl' + index + '-1').removeClass('btn-primary btn-success').addClass('btn-primary')
.unbind('click').click(function() {
var index = $(this).attr('id').split('sl')[1].split('-')[0];
toastr.info("Switching simulcast substream (mid=" + mids[index] + "), wait for it... (normal quality)", null, {timeOut: 2000});
let index = $(this).attr('id').split('sl')[1].split('-')[0];
toastr.info("Switching " + what + " " + layer + " (mid=" + mids[index] + "), wait for it... (normal quality)", null, {timeOut: 2000});
if(!$('#sl' + index + '-2').hasClass('btn-success'))
$('#sl' + index + '-2').removeClass('btn-primary btn-info').addClass('btn-primary');
$('#sl' + index + '-1').removeClass('btn-primary btn-info btn-success').addClass('btn-info');
if(!$('#sl' + index + '-0').hasClass('btn-success'))
$('#sl' + index + '-0').removeClass('btn-primary btn-info').addClass('btn-primary');
remoteFeed.send({ message: { request: "configure", mid: mids[index], substream: 1 }});
if(simulcastStarted[index])
remoteFeed.send({ message: { request: "configure", mid: mids[index], substream: 1 }});
else
remoteFeed.send({ message: { request: "configure", mid: mids[index], spatial_layer: 1 }});
});
$('#sl' + index + '-2').removeClass('btn-primary btn-success').addClass('btn-primary')
.unbind('click').click(function() {
var index = $(this).attr('id').split('sl')[1].split('-')[0];
toastr.info("Switching simulcast substream (mid=" + mids[index] + "), wait for it... (higher quality)", null, {timeOut: 2000});
let index = $(this).attr('id').split('sl')[1].split('-')[0];
toastr.info("Switching " + what + " " + layer + " (mid=" + mids[index] + "), wait for it... (higher quality)", null, {timeOut: 2000});
$('#sl' + index + '-2').removeClass('btn-primary btn-info btn-success').addClass('btn-info');
if(!$('#sl' + index + '-1').hasClass('btn-success'))
$('#sl' + index + '-1').removeClass('btn-primary btn-info').addClass('btn-primary');
if(!$('#sl' + index + '-0').hasClass('btn-success'))
$('#sl' + index + '-0').removeClass('btn-primary btn-info').addClass('btn-primary');
remoteFeed.send({ message: { request: "configure", mid: mids[index], substream: 2 }});
if(simulcastStarted[index])
remoteFeed.send({ message: { request: "configure", mid: mids[index], substream: 2 }});
else
remoteFeed.send({ message: { request: "configure", mid: mids[index], spatial_layer: 2 }});
});
if(!temporal) // No temporal layer support
if(!temporal) // No temporal layer support
return;
$('#tl' + index + '-0').parent().removeClass('hide');
$('#tl' + index + '-0').removeClass('btn-primary btn-success').addClass('btn-primary')
.unbind('click').click(function() {
var index = $(this).attr('id').split('tl')[1].split('-')[0];
toastr.info("Capping simulcast temporal layer (mid=" + mids[index] + "), wait for it... (lowest FPS)", null, {timeOut: 2000});
let index = $(this).attr('id').split('tl')[1].split('-')[0];
toastr.info("Capping " + what + " temporal layer (mid=" + mids[index] + "), wait for it... (lowest FPS)", null, {timeOut: 2000});
if(!$('#tl' + index + '-2').hasClass('btn-success'))
$('#tl' + index + '-2').removeClass('btn-primary btn-info').addClass('btn-primary');
if(!$('#tl' + index + '-1').hasClass('btn-success'))
$('#tl' + index + '-1').removeClass('btn-primary btn-info').addClass('btn-primary');
$('#tl' + index + '-0').removeClass('btn-primary btn-info btn-success').addClass('btn-info');
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal: 0 }});
if(simulcastStarted[index])
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal: 0 }});
else
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal_layer: 0 }});
});
$('#tl' + index + '-1').removeClass('btn-primary btn-success').addClass('btn-primary')
.unbind('click').click(function() {
var index = $(this).attr('id').split('tl')[1].split('-')[0];
toastr.info("Capping simulcast temporal layer (mid=" + mids[index] + "), wait for it... (medium FPS)", null, {timeOut: 2000});
let index = $(this).attr('id').split('tl')[1].split('-')[0];
toastr.info("Capping " + what + " temporal layer (mid=" + mids[index] + "), wait for it... (medium FPS)", null, {timeOut: 2000});
if(!$('#tl' + index + '-2').hasClass('btn-success'))
$('#tl' + index + '-2').removeClass('btn-primary btn-info').addClass('btn-primary');
$('#tl' + index + '-1').removeClass('btn-primary btn-info').addClass('btn-info');
if(!$('#tl' + index + '-0').hasClass('btn-success'))
$('#tl' + index + '-0').removeClass('btn-primary btn-info').addClass('btn-primary');
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal: 1 }});
if(simulcastStarted[index])
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal: 1 }});
else
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal_layer: 1 }});
});
$('#tl' + index + '-2').removeClass('btn-primary btn-success').addClass('btn-primary')
.unbind('click').click(function() {
var index = $(this).attr('id').split('tl')[1].split('-')[0];
toastr.info("Capping simulcast temporal layer (mid=" + mids[index] + "), wait for it... (highest FPS)", null, {timeOut: 2000});
let index = $(this).attr('id').split('tl')[1].split('-')[0];
toastr.info("Capping " + what + " temporal layer (mid=" + mids[index] + "), wait for it... (highest FPS)", null, {timeOut: 2000});
$('#tl' + index + '-2').removeClass('btn-primary btn-info btn-success').addClass('btn-info');
if(!$('#tl' + index + '-1').hasClass('btn-success'))
$('#tl' + index + '-1').removeClass('btn-primary btn-info').addClass('btn-primary');
if(!$('#tl' + index + '-0').hasClass('btn-success'))
$('#tl' + index + '-0').removeClass('btn-primary btn-info').addClass('btn-primary');
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal: 2 }});
if(simulcastStarted[index])
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal: 2 }});
else
remoteFeed.send({ message: { request: "configure", mid: mids[index], temporal_layer: 2 }});
});
}
function updateSimulcastButtons(feed, substream, temporal) {
function updateSimulcastSvcButtons(feed, substream, temporal) {
// Check the substream
var index = feed;
let index = feed;
let simulcast = simulcastStarted[index];
let what = (simulcast ? 'simulcast' : 'SVC');
let layer = (simulcast ? 'substream' : 'layer');
if(substream === 0) {
toastr.success("Switched simulcast substream! (lower quality)", null, {timeOut: 2000});
toastr.success("Switched " + what + " " + layer + "! (lower quality)", null, {timeOut: 2000});
$('#sl' + index + '-2').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#sl' + index + '-1').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#sl' + index + '-0').removeClass('btn-primary btn-info btn-success').addClass('btn-success');
} else if(substream === 1) {
toastr.success("Switched simulcast substream! (normal quality)", null, {timeOut: 2000});
toastr.success("Switched " + what + " " + layer + "! (normal quality)", null, {timeOut: 2000});
$('#sl' + index + '-2').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#sl' + index + '-1').removeClass('btn-primary btn-info btn-success').addClass('btn-success');
$('#sl' + index + '-0').removeClass('btn-primary btn-success').addClass('btn-primary');
} else if(substream === 2) {
toastr.success("Switched simulcast substream! (higher quality)", null, {timeOut: 2000});
toastr.success("Switched " + what + " " + layer + "! (higher quality)", null, {timeOut: 2000});
$('#sl' + index + '-2').removeClass('btn-primary btn-info btn-success').addClass('btn-success');
$('#sl' + index + '-1').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#sl' + index + '-0').removeClass('btn-primary btn-success').addClass('btn-primary');
}
// Check the temporal layer
if(temporal === 0) {
toastr.success("Capped simulcast temporal layer! (lowest FPS)", null, {timeOut: 2000});
toastr.success("Capped " + what + " temporal layer! (lowest FPS)", null, {timeOut: 2000});
$('#tl' + index + '-2').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#tl' + index + '-1').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#tl' + index + '-0').removeClass('btn-primary btn-info btn-success').addClass('btn-success');
} else if(temporal === 1) {
toastr.success("Capped simulcast temporal layer! (medium FPS)", null, {timeOut: 2000});
toastr.success("Capped " + what + " temporal layer! (medium FPS)", null, {timeOut: 2000});
$('#tl' + index + '-2').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#tl' + index + '-1').removeClass('btn-primary btn-info btn-success').addClass('btn-success');
$('#tl' + index + '-0').removeClass('btn-primary btn-success').addClass('btn-primary');
} else if(temporal === 2) {
toastr.success("Capped simulcast temporal layer! (highest FPS)", null, {timeOut: 2000});
toastr.success("Capped " + what + " temporal layer! (highest FPS)", null, {timeOut: 2000});
$('#tl' + index + '-2').removeClass('btn-primary btn-info btn-success').addClass('btn-success');
$('#tl' + index + '-1').removeClass('btn-primary btn-success').addClass('btn-primary');
$('#tl' + index + '-0').removeClass('btn-primary btn-success').addClass('btn-primary');

View File

@ -4,7 +4,7 @@
# This file based on example code from Janus which is
# licensed as follows.
#
# 2014-2022 Meetecho
# 2014-2025 Meetecho
#
# GPL-3 with OpenSSL exception
# If you modify this Program, or any covered work,
@ -21,7 +21,7 @@
{% load static %}
{% load i18n %}
<!DOCTYPE HTML>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
@ -34,13 +34,13 @@
<script type="text/javascript"
src="/javascript/jquery/jquery.min.js" ></script>
<script type="text/javascript"
src="/javascript/jquery-blockui/jquery.blockUI.js" ></script>
src="/javascript/popperjs2/popper.min.js"></script>
<script type="text/javascript"
src="/javascript/bootstrap/js/bootstrap.min.js" ></script>
src="/javascript/jquery-blockui/jquery.blockUI.min.js" ></script>
<script type="text/javascript"
src="/javascript/bootstrap5/js/bootstrap.min.js" ></script>
<script type="text/javascript"
src="/javascript/bootbox/bootbox.min.js" ></script>
<script type="text/javascript"
src="/javascript/spin.js/spin.min.js" ></script>
<script type="text/javascript"
src="/javascript/toastr/toastr.min.js" ></script>
<script type="text/javascript"
@ -51,22 +51,26 @@
src="{% static 'janus/janus-video-room.js' %}" ></script>
<link rel="stylesheet"
href="/javascript/bootswatch/cerulean/bootstrap.min.css"
href="/javascript/bootstrap5/css/bootstrap.css"
type="text/css"/>
<link rel="stylesheet" href="/javascript/toastr/toastr.min.css"
type="text/css"/>
<link rel="stylesheet"
href="{% static 'janus/janus-video-room.css' %}" type="text/css"/>
<link rel="stylesheet"
href="/javascript/font-awesome/css/font-awesome.min.css" type="text/css"/>
</head>
<body data-user-turn-config="{{ user_turn_config }}">
<div class="container" id="content" role="main">
<div class="row">
<div class="col-md-12">
<h1>Janus Video Room
<button class="btn btn-default" autocomplete="off"
id="start">Start</button>
</h1>
<div class="pb-2 mt-4 mb-2 border-bottom">
<h1>Janus Video Room
<button class="btn btn-default" autocomplete="off"
id="start">Start</button>
</h1>
</div>
</div>
<div class="container" id="details">
@ -86,12 +90,12 @@
</div>
</div>
<div class="container hide" id="videojoin">
<div class="container mt-4 hide" id="videojoin">
<div class="row">
<span class="label label-info" id="you"></span>
<span class="badge bg-info" id="you"></span>
<div class="col-md-12" id="controls">
<div class="input-group margin-bottom-md hide" id="registernow">
<span class="input-group-addon">@</span>
<div class="input-group mt-3 mb-1 hide" id="registernow">
<span class="input-group-text">👤</span>
<input autocomplete="off" class="form-control"
autocomplete="off" type="text"
placeholder="Choose a display name"
@ -106,93 +110,88 @@
</div>
</div>
<div class="container hide" id="videos">
<div class="container mt-4 hide" id="videos">
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Local Video <span class="label label-primary hide"
<div class="card">
<div class="card-header">
<span class="card-title">
Local Video <span class="badge bg-primary hide"
id="publisher"></span>
<div class="btn-group btn-group-xs pull-right hide">
<div class="btn-group btn-group-xs">
<div class="btn-group btn-group-sm top-right hide">
<div class="btn-group btn-group-sm">
<button id="bitrateset" autocomplete="off"
class="btn btn-primary
dropdown-toggle"
data-toggle="dropdown">
Bandwidth<span class="caret"></span>
data-bs-toggle="dropdown">
Bandwidth
</button>
<ul id="bitrate" class="dropdown-menu" role="menu">
<li><a href="#" id="0">No limit</a></li>
<li><a href="#" id="128">Cap to 128kbit</a></li>
<li><a href="#" id="256">Cap to 256kbit</a></li>
<li><a href="#" id="512">Cap to 512kbit</a></li>
<li><a href="#" id="1024">Cap to 1mbit</a></li>
<li><a href="#" id="1500">Cap to 1.5mbit</a></li>
<li><a href="#" id="2000">Cap to 2mbit</a></li>
<a class="dropdown-item" href="#" id="0">No limit</a>
<a class="dropdown-item" href="#" id="128">Cap to 128kbit</a>
<a class="dropdown-item" href="#" id="256">Cap to 256kbit</a>
<a class="dropdown-item" href="#" id="512">Cap to 512kbit</a>
<a class="dropdown-item" href="#" id="1024">Cap to 1mbit</a>
<a class="dropdown-item" href="#" id="1500">Cap to 1.5mbit</a>
<a class="dropdown-item" href="#" id="2000">Cap to 2mbit</a>
</ul>
</div>
</div>
</h3>
</span>
</div>
<div class="panel-body" id="videolocal"></div>
<div class="card-body" id="videolocal"></div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Remote Video #1 <span class="label label-info hide"
id="remote1"></span>
</h3>
<div class="card">
<div class="card-header">
<span class="card-title">
Remote Video #1 <span class="badge bg-info hide"
id="remote1"></span></span>
</div>
<div class="panel-body relative" id="videoremote1"></div>
<div class="card-body relative" id="videoremote1"></div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Remote Video #2 <span class="label label-info hide"
id="remote2"></span>
</h3>
<div class="card">
<div class="card-header">
<span class="card-title">
Remote Video #2 <span class="badge bg-info hide"
id="remote2"></span></span>
</div>
<div class="panel-body relative" id="videoremote2"></div>
<div class="card-body relative" id="videoremote2"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Remote Video #3 <span class="label label-info hide"
id="remote3"></span>
</h3>
<div class="card">
<div class="card-header">
<span class="card-title">
Remote Video #3 <span class="badge bg-info hide"
id="remote3"></span></span>
</div>
<div class="panel-body relative" id="videoremote3"></div>
<div class="card-body relative" id="videoremote3"></div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Remote Video #4 <span class="label label-info hide"
id="remote4"></span>
</h3>
<div class="card">
<div class="card-header">
<span class="card-title">
Remote Video #4 <span class="badge bg-info hide"
id="remote4"></span></span>
</div>
<div class="panel-body relative" id="videoremote4"></div>
<div class="card-body relative" id="videoremote4"></div>
</div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Remote Video #5 <span class="label label-info hide"
id="remote5"></span>
</h3>
<div class="card">
<div class="card-header">
<span class="card-title">
Remote Video #5 <span class="badge bg-info hide"
id="remote5"></span></span>
</div>
<div class="panel-body relative" id="videoremote5"></div>
<div class="card-body relative" id="videoremote5"></div>
</div>
</div>
</div>

View File

@ -3,14 +3,26 @@
Views for the Janus app.
"""
import copy
from django.views.generic import TemplateView
from plinth import app as app_module
from plinth.middleware import CONTENT_SECURITY_POLICY
class JanusRoomView(TemplateView):
"""A simple page to host Janus video room."""
template_name = 'janus_video_room.html'
headers: dict[str, str] = {}
def __init__(self, **kwargs):
"""Initialize the view and set CSP."""
super().__init__(**kwargs)
csp = copy.copy(CONTENT_SECURITY_POLICY)
csp['script-src'] = "'self' 'unsafe-inline'"
csp['style-src'] = "'self' 'unsafe-inline'"
self.headers['Content-Security-Policy'] = csp.get_header_value()
def get_context_data(self, *args, **kwargs):
"""Add user's TURN server information to view context."""
@ -19,3 +31,8 @@ class JanusRoomView(TemplateView):
context = super().get_context_data(*args, **kwargs)
context['user_turn_config'] = config.to_json()
return context
def get(self, request, *args, **kwargs):
"""Handle GET request and return a response object."""
context = self.get_context_data(**kwargs)
return self.render_to_response(context, headers=self.headers)

View File

@ -53,7 +53,11 @@ class JSXCApp(app_module.App):
clients=info.clients, tags=info.tags)
self.add(shortcut)
packages = Packages('packages-jsxc', ['libjs-jsxc'])
packages = Packages('packages-jsxc', [
'libjs-jsxc', 'libjs-bootstrap4', 'libjs-jquery',
'libjs-jquery-ui', 'node-jquery-slimscroll',
'libjs-jquery-fullscreen'
])
self.add(packages)
firewall = Firewall('firewall-jsxc', info.name,

View File

@ -48,7 +48,7 @@
<script src="/javascript/jquery/jquery.min.js"></script>
<script src="/javascript/jquery-ui/jquery-ui.min.js"></script>
<script src="/javascript/jquery-slimscroll/jquery.slimscroll.min.js"></script>
<script src="/javascript/jquery-slimscroll/jquery-slimscroll.min.js"></script>
<script src="/javascript/jquery-fullscreen/jquery.fullscreen.js"></script>
<script src="/javascript/bootstrap4/js/bootstrap.bundle.min.js"></script>
<script src="/javascript/jsxc/lib/jsxc.dep.js"></script>

View File

@ -1,10 +1,13 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Views for the JSXC module."""
import copy
from django.http import Http404
from django.views.generic import TemplateView
import plinth.app as app_module
from plinth.middleware import CONTENT_SECURITY_POLICY
from plinth.modules.names.components import DomainName
@ -12,6 +15,14 @@ class JsxcView(TemplateView):
"""A simple page to embed Javascript XMPP Client library."""
template_name = 'jsxc_launch.html'
headers: dict[str, str] = {}
def __init__(self, **kwargs):
"""Initialize the view and set CSP."""
super().__init__(**kwargs)
csp = copy.copy(CONTENT_SECURITY_POLICY)
csp['style-src'] = "'self' 'unsafe-inline'"
self.headers['Content-Security-Policy'] = csp.get_header_value()
def dispatch(self, request, *args, **kwargs):
"""Don't serve the view when app is disabled."""
@ -26,3 +37,8 @@ class JsxcView(TemplateView):
context = super().get_context_data(*args, **kwargs)
context['domain_name'] = DomainName.list_names()[0]
return context
def get(self, request, *args, **kwargs):
"""Handle GET request and return a response object."""
context = self.get_context_data(**kwargs)
return self.render_to_response(context, headers=self.headers)

View File

@ -55,7 +55,7 @@ class UpgradesApp(app_module.App):
app_id = 'upgrades'
_version = 20
_version = 21
can_be_disabled = False

View File

@ -74,6 +74,17 @@ Explanation: matrix-synapse recommends python3-pympler
Package: python3-pympler
Pin: release n=sid
Pin-Priority: 200
Explanation: Make janus package and its dependencies installable from Debian
Explanation: 'unstable' distribution.
Package: janus
Pin: release n=sid
Pin-Priority: 200
Explanation: Janus app in FreedomBox needs the package for web UI.
Package: libjs-janus-gateway
Pin: release n=sid
Pin-Priority: 200
'''
APT_PREFERENCES_UNSTABLE = \

View File

@ -308,9 +308,9 @@ class Packages(app_module.FollowerComponent):
"""
packages_set: set[str] = set(packages)
# Get list of packages needed by other installed apps (packages to
# keep).
keep_packages: set[str] = set()
# Get list of packages needed by other installed apps and by freedombox
# itself (packages to keep).
keep_packages: set[str] = {'freedombox'}
for app in app_module.App.list():
# uninstall() will be called on Packages of this app separately
# for uninstalling this app.

View File

@ -149,6 +149,7 @@ LOGIN_REDIRECT_URL = 'index'
MESSAGE_TAGS: dict = {}
MIDDLEWARE = (
'plinth.middleware.CommonHeadersMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',

View File

@ -178,11 +178,11 @@ def test_packages_uninstall(uninstall, _refresh_package_lists):
"""Test app"""
app_id = 'test-app'
component = Packages('test-component', ['python3', 'bash'])
component = Packages('test-component', ['bash', 'dash'])
app = TestApp()
app.add(component)
app.uninstall()
uninstall.assert_has_calls([call(['python3', 'bash'], purge=True)])
uninstall.assert_has_calls([call(['bash', 'dash'], purge=True)])
@patch('plinth.package.refresh_package_lists')