From d46c0d7258f65050aba34b116c9121389465f430 Mon Sep 17 00:00:00 2001
From: Burak Yavuz
Date: Tue, 5 Nov 2024 04:15:32 +0000
Subject: [PATCH 01/25] Translated using Weblate (Turkish)
Currently translated at 100.0% (1770 of 1770 strings)
---
plinth/locale/tr/LC_MESSAGES/django.po | 48 ++++++++++++--------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/plinth/locale/tr/LC_MESSAGES/django.po b/plinth/locale/tr/LC_MESSAGES/django.po
index 1313a8501..f93ed4784 100644
--- a/plinth/locale/tr/LC_MESSAGES/django.po
+++ b/plinth/locale/tr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 20:11-0500\n"
-"PO-Revision-Date: 2024-10-23 05:15+0000\n"
+"PO-Revision-Date: 2024-11-06 05:06+0000\n"
"Last-Translator: Burak Yavuz \n"
"Language-Team: Turkish \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.8.2-dev\n"
+"X-Generator: Weblate 5.8.2\n"
#: config.py:103
#, python-brace-format
@@ -321,6 +321,9 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
+"Yerel bilgisayardan yüklenecek yedekleme dosyasını seçin. Bu, daha önce "
+"{box_name} üzerinde başarılı bir yedekleme sonucunda indirilen bir dosya "
+"olmak zorundadır. .tar.gz uzantısına sahip olmak zorundadır."
#: modules/backups/forms.py:152
msgid "Repository path format incorrect."
@@ -2959,10 +2962,8 @@ msgstr ""
"edilebilir."
#: modules/help/templates/help_about.html:85
-#, fuzzy
-#| msgid "Learn more"
msgid "Learn"
-msgstr "Daha fazla bilgi edinin"
+msgstr "Bilgi edinin"
#: modules/help/templates/help_about.html:88
msgid "Homepage"
@@ -2974,17 +2975,15 @@ msgstr "Bağış"
#: modules/help/templates/help_about.html:107
msgid "Join project"
-msgstr ""
+msgstr "Projeye katıl"
#: modules/help/templates/help_about.html:111
msgid "Translate"
-msgstr ""
+msgstr "Çevir"
#: modules/help/templates/help_about.html:117
-#, fuzzy
-#| msgid "Get Support"
msgid "Support"
-msgstr "Destek Al"
+msgstr "Destek"
#: modules/help/templates/help_about.html:121
msgid "Forum"
@@ -8889,22 +8888,21 @@ msgstr ""
"başlayan satırlar yoksayılacaktır."
#: modules/users/forms.py:252
-#, fuzzy
-#| msgid "Delete User"
msgid "Delete user"
-msgstr "Kullanıcıyı Sil"
+msgstr "Kullanıcıyı sil"
#: modules/users/forms.py:254
msgid ""
"Deleting the user account will also remove all the files related to the "
"user. Deleting files can be avoided by setting the user account as inactive."
msgstr ""
+"Kullanıcı hesabının silinmesi, kullanıcıyla ilgili tüm dosyaları da "
+"kaldıracaktır. Kullanıcı hesabının etkin değil olarak ayarlanmasıyla "
+"dosyaların silinmesi önlenebilir."
#: modules/users/forms.py:305
-#, fuzzy
-#| msgid "Failed to add user to group."
msgid "Failed to delete user."
-msgstr "Kullanıcıyı gruba ekleme başarısız oldu."
+msgstr "Kullanıcıyı silme başarısız oldu."
#: modules/users/forms.py:320
msgid "Renaming LDAP user failed."
@@ -9029,10 +9027,10 @@ msgid "Save Changes"
msgstr "Değişiklikleri Kaydet"
#: modules/users/templates/users_update.html:41
-#, fuzzy, python-format
-#| msgid "Delete user %(username)s permanently?"
+#, python-format
msgid "Delete user %(username)s and all the user's files?"
-msgstr "%(username)s kullanıcısı kalıcı olarak silinsin mi?"
+msgstr ""
+"%(username)s kullanıcısı ve kullanıcının tüm dosyaları silinsin mi?"
#: modules/users/templates/users_update.html:46 templates/messages.html:11
msgid "Close"
@@ -9043,12 +9041,13 @@ msgid ""
"Deleting a user account also removes all the files user's home directory. If "
"you wish to keep these files, disable the user account instead."
msgstr ""
+"Bir kullanıcı hesabının silinmesi aynı zamanda kullanıcının ana dizinindeki "
+"tüm dosyaları da kaldırır. Eğer bu dosyaları saklamak istiyorsanız, bunun "
+"yerine kullanıcı hesabını etkisizleştirin."
#: modules/users/templates/users_update.html:59
-#, fuzzy
-#| msgid "Delete files"
msgid "Delete user and files"
-msgstr "Dosyaları sil"
+msgstr "Kullanıcı ve dosyaları sil"
#: modules/users/templates/users_update.html:62
msgid "Cancel"
@@ -9069,10 +9068,9 @@ msgid "Edit User"
msgstr "Kullanıcıyı Düzenle"
#: modules/users/views.py:111
-#, fuzzy, python-format
-#| msgid "User %(username)s created."
+#, python-format
msgid "User %(username)s deleted."
-msgstr "%(username)s kullanıcısı oluşturuldu."
+msgstr "%(username)s kullanıcısı silindi."
#: modules/users/views.py:130
msgid "Change Password"
From 1f3612e0ec67b996c4b5ac52c8d3670cb11049df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A4=A7=E7=8E=8B=E5=8F=AB=E6=88=91=E6=9D=A5=E5=B7=A1?=
=?UTF-8?q?=E5=B1=B1?=
Date: Tue, 5 Nov 2024 10:36:15 +0000
Subject: [PATCH 02/25] Translated using Weblate (Chinese (Simplified Han
script))
Currently translated at 63.5% (1125 of 1770 strings)
---
plinth/locale/zh_Hans/LC_MESSAGES/django.po | 32 +++++++--------------
1 file changed, 10 insertions(+), 22 deletions(-)
diff --git a/plinth/locale/zh_Hans/LC_MESSAGES/django.po b/plinth/locale/zh_Hans/LC_MESSAGES/django.po
index 50db30470..d2d447782 100644
--- a/plinth/locale/zh_Hans/LC_MESSAGES/django.po
+++ b/plinth/locale/zh_Hans/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Plinth\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 20:11-0500\n"
-"PO-Revision-Date: 2024-10-23 05:15+0000\n"
+"PO-Revision-Date: 2024-11-06 05:06+0000\n"
"Last-Translator: 大王叫我来巡山 \n"
"Language-Team: Chinese (Simplified Han script) %(username)s permanently?"
+#, python-format
msgid "Delete user %(username)s and all the user's files?"
-msgstr "永久删除用户 %(username)s?"
+msgstr "删除用户 %(username)s 及该用户所有文件?"
#: modules/users/templates/users_update.html:46 templates/messages.html:11
msgid "Close"
@@ -8165,10 +8156,8 @@ msgid ""
msgstr ""
#: modules/users/templates/users_update.html:59
-#, fuzzy
-#| msgid "Delete files"
msgid "Delete user and files"
-msgstr "删除文件"
+msgstr "删除用户和文件"
#: modules/users/templates/users_update.html:62
msgid "Cancel"
@@ -8189,10 +8178,9 @@ msgid "Edit User"
msgstr "编辑用户"
#: modules/users/views.py:111
-#, fuzzy, python-format
-#| msgid "User %(username)s created."
+#, python-format
msgid "User %(username)s deleted."
-msgstr "用户 %(username)s 已创建。"
+msgstr "用户 %(username)s 已被删除。"
#: modules/users/views.py:130
msgid "Change Password"
From 01f28a1d45ba21d6cbc8be7b3fa47d60b509d262 Mon Sep 17 00:00:00 2001
From: 109247019824
Date: Tue, 5 Nov 2024 06:37:12 +0000
Subject: [PATCH 03/25] Translated using Weblate (Bulgarian)
Currently translated at 46.8% (829 of 1770 strings)
---
plinth/locale/bg/LC_MESSAGES/django.po | 57 ++++++++++++--------------
1 file changed, 27 insertions(+), 30 deletions(-)
diff --git a/plinth/locale/bg/LC_MESSAGES/django.po b/plinth/locale/bg/LC_MESSAGES/django.po
index 9204fc241..1762faa69 100644
--- a/plinth/locale/bg/LC_MESSAGES/django.po
+++ b/plinth/locale/bg/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 20:11-0500\n"
-"PO-Revision-Date: 2024-10-23 05:15+0000\n"
+"PO-Revision-Date: 2024-11-06 05:06+0000\n"
"Last-Translator: 109247019824 \n"
"Language-Team: Bulgarian \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.8.2-dev\n"
+"X-Generator: Weblate 5.8.2\n"
#: config.py:103
#, python-brace-format
@@ -244,7 +244,7 @@ msgid ""
"This many latest backups are kept and the rest are removed. A value of \"0\" "
"disables backups of this type. Triggered at specified hour every day."
msgstr ""
-"Такова броя от последните резервни копия ще бъдат запазвани, а останалите - "
+"Такова броя от последните резервни копия ще бъдат запазвани, а останалите – "
"премахвани. Стойност „0“ изключва този вид резервно копие. Изпълнява се в "
"определен час всеки ден."
@@ -326,6 +326,9 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
+"Изберете файла с резервно копие, който да изпратите от компютъра. Това "
+"трябва да бъде файл, резултат от успешно резервно копие на {box_name}, който "
+"е бил изтеглен предварително. Трябва да има разширение .tar.gz."
#: modules/backups/forms.py:152
msgid "Repository path format incorrect."
@@ -2776,10 +2779,8 @@ msgid ""
msgstr ""
#: modules/help/templates/help_about.html:85
-#, fuzzy
-#| msgid "Learn more"
msgid "Learn"
-msgstr "Научете повече"
+msgstr "Научете"
#: modules/help/templates/help_about.html:88
msgid "Homepage"
@@ -2791,17 +2792,15 @@ msgstr "Дарение"
#: modules/help/templates/help_about.html:107
msgid "Join project"
-msgstr ""
+msgstr "Присъединете се към проекта"
#: modules/help/templates/help_about.html:111
msgid "Translate"
-msgstr ""
+msgstr "Превеждане"
#: modules/help/templates/help_about.html:117
-#, fuzzy
-#| msgid "Get Support"
msgid "Support"
-msgstr "Получаване на помощ"
+msgstr "Поддръжка"
#: modules/help/templates/help_about.html:121
msgid "Forum"
@@ -8147,8 +8146,6 @@ msgstr ""
"бъдат пренебрегнати."
#: modules/users/forms.py:252
-#, fuzzy
-#| msgid "Delete User"
msgid "Delete user"
msgstr "Премахване на потребител"
@@ -8157,12 +8154,12 @@ msgid ""
"Deleting the user account will also remove all the files related to the "
"user. Deleting files can be avoided by setting the user account as inactive."
msgstr ""
+"Премахването на профил на потребител ще премахне и всички прилежащи файлове. "
+"Премахването на файлове може да бъде избегнато, като профилът бъде изключен."
#: modules/users/forms.py:305
-#, fuzzy
-#| msgid "Failed to add user to group."
msgid "Failed to delete user."
-msgstr "Потребителят не е добавен към групата."
+msgstr "Потребителят не е премахнат."
#: modules/users/forms.py:320
msgid "Renaming LDAP user failed."
@@ -8288,31 +8285,32 @@ msgid "Save Changes"
msgstr "Запазване на промените"
#: modules/users/templates/users_update.html:41
-#, fuzzy, python-format
-#| msgid "Delete user %(username)s permanently?"
+#, python-format
msgid "Delete user %(username)s and all the user's files?"
msgstr ""
-"Потвърждавате ли премахването на потребителя %(username)s?"
+"Потвърждавате ли премахването на потребителя %(username)s и всички "
+"негови файлове?"
#: modules/users/templates/users_update.html:46 templates/messages.html:11
msgid "Close"
-msgstr ""
+msgstr "Затваряне"
#: modules/users/templates/users_update.html:51
msgid ""
"Deleting a user account also removes all the files user's home directory. If "
"you wish to keep these files, disable the user account instead."
msgstr ""
+"При премахване на профил на потребител се премахват и всички файлове от "
+"домашната му папка. Ако желаете тези файлове да бъдат запазени, вместо да "
+"премахвате профила го изключете.."
#: modules/users/templates/users_update.html:59
-#, fuzzy
-#| msgid "Delete %(username)s"
msgid "Delete user and files"
-msgstr "Премахване на %(username)s"
+msgstr "Премахване на файловете на %(username)s"
#: modules/users/templates/users_update.html:62
msgid "Cancel"
-msgstr ""
+msgstr "Отказ"
#: modules/users/views.py:41
#, python-format
@@ -8329,10 +8327,9 @@ msgid "Edit User"
msgstr "Промяна на потребител"
#: modules/users/views.py:111
-#, fuzzy, python-format
-#| msgid "User %(username)s created."
+#, python-format
msgid "User %(username)s deleted."
-msgstr "Потребителят %(username)s е създаден."
+msgstr "Потребителят %(username)s е премахнат."
#: modules/users/views.py:130
msgid "Change Password"
@@ -8730,7 +8727,7 @@ msgstr "Zoph"
#: modules/zoph/__init__.py:57
msgid "Photo Organizer"
-msgstr ""
+msgstr "Организатор на фотографии"
#: modules/zoph/forms.py:14
msgid "Enable OpenStreetMap for maps"
@@ -8746,7 +8743,7 @@ msgstr ""
#: modules/zoph/manifest.py:26
msgid "Photo"
-msgstr ""
+msgstr "Фотографии"
#: modules/zoph/manifest.py:26
msgid "Organizer"
@@ -8946,7 +8943,7 @@ msgstr "Услугата %(service_name)s не работи."
#: templates/apps.html:29
msgid "Search with tags"
-msgstr ""
+msgstr "Търсене по етикети"
#: templates/base.html:31
msgid ""
From ff4250f24ee8bf29c3571d2822f245385181e651 Mon Sep 17 00:00:00 2001
From: Besnik Bleta
Date: Tue, 5 Nov 2024 09:30:08 +0000
Subject: [PATCH 04/25] Translated using Weblate (Albanian)
Currently translated at 99.7% (1766 of 1770 strings)
---
plinth/locale/sq/LC_MESSAGES/django.po | 52 +++++++++++++-------------
1 file changed, 25 insertions(+), 27 deletions(-)
diff --git a/plinth/locale/sq/LC_MESSAGES/django.po b/plinth/locale/sq/LC_MESSAGES/django.po
index dbe846e8d..2dd432d56 100644
--- a/plinth/locale/sq/LC_MESSAGES/django.po
+++ b/plinth/locale/sq/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 20:11-0500\n"
-"PO-Revision-Date: 2024-10-23 05:15+0000\n"
+"PO-Revision-Date: 2024-11-06 05:06+0000\n"
"Last-Translator: Besnik Bleta \n"
"Language-Team: Albanian \n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.8.2-dev\n"
+"X-Generator: Weblate 5.8.2\n"
#: config.py:103
#, python-brace-format
@@ -325,6 +325,10 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
+"Përzgjidhni kartelën kopjeruajtje për t’u ngarkuar nga kompjuteri vendor. "
+"Kjo duhet të jetë një kartelë e shkarkuar më herët nga përfundimi i një "
+"kojeruajtjeje të suksesshme te një {box_name}. Duhet të ketë zgjatimin .tar."
+"gz."
#: modules/backups/forms.py:152
msgid "Repository path format incorrect."
@@ -2975,10 +2979,8 @@ msgstr ""
"emër_pakete” në një terminal (duke përdorur Cockpit, ose SSH)."
#: modules/help/templates/help_about.html:85
-#, fuzzy
-#| msgid "Learn more"
msgid "Learn"
-msgstr "Mësoni më tepër"
+msgstr "Mësoni"
#: modules/help/templates/help_about.html:88
msgid "Homepage"
@@ -2990,17 +2992,15 @@ msgstr "Dhuroni"
#: modules/help/templates/help_about.html:107
msgid "Join project"
-msgstr ""
+msgstr "Merrni pjesë te projekti"
#: modules/help/templates/help_about.html:111
msgid "Translate"
-msgstr ""
+msgstr "Përktheni"
#: modules/help/templates/help_about.html:117
-#, fuzzy
-#| msgid "Get Support"
msgid "Support"
-msgstr "Merrni Asistencë"
+msgstr "Asistencë"
#: modules/help/templates/help_about.html:121
msgid "Forum"
@@ -4612,7 +4612,7 @@ msgstr "Mumla"
#: modules/mumble/manifest.py:67
msgid "Group conference"
-msgstr ""
+msgstr "Konferencë grupi"
#: modules/mumble/manifest.py:67 modules/radicale/manifest.py:91
#: modules/shadowsocks/forms.py:24
@@ -4758,7 +4758,7 @@ msgstr "Shërbime"
#: modules/names/templates/names.html:56
msgid "Resolver Status"
-msgstr ""
+msgstr "Gjendje Zgjidhësi"
#: modules/names/templates/names.html:66
msgid "Global"
@@ -8943,22 +8943,21 @@ msgstr ""
"shpërfillen."
#: modules/users/forms.py:252
-#, fuzzy
-#| msgid "Delete User"
msgid "Delete user"
-msgstr "Fshi Përdorues"
+msgstr "Fshi përdorues"
#: modules/users/forms.py:254
msgid ""
"Deleting the user account will also remove all the files related to the "
"user. Deleting files can be avoided by setting the user account as inactive."
msgstr ""
+"Fshirja e llogarisë do të heqë gjithashtu krejt kartelat e lidhura me "
+"përdoruesin. Fshirja e kartelave mund të shmanget duke e vënë llogarinë e "
+"përdoruesit si joaktive."
#: modules/users/forms.py:305
-#, fuzzy
-#| msgid "Failed to add user to group."
msgid "Failed to delete user."
-msgstr "S’u arrit të shtohej përdorues te grup."
+msgstr "S’u arrit të fshihej përdorues."
#: modules/users/forms.py:320
msgid "Renaming LDAP user failed."
@@ -9086,10 +9085,9 @@ msgid "Save Changes"
msgstr "Ruaji Ndryshimet"
#: modules/users/templates/users_update.html:41
-#, fuzzy, python-format
-#| msgid "Delete user %(username)s permanently?"
+#, python-format
msgid "Delete user %(username)s and all the user's files?"
-msgstr "Të fshihet përgjithnjë përdoruesi %(username)s?"
+msgstr "Të fshihet përdoruesi %(username)s dhe krejt kartelat e përdoruesit?"
#: modules/users/templates/users_update.html:46 templates/messages.html:11
msgid "Close"
@@ -9100,12 +9098,13 @@ msgid ""
"Deleting a user account also removes all the files user's home directory. If "
"you wish to keep these files, disable the user account instead."
msgstr ""
+"Fshirja e llogarisë do të heqë gjithashtu krejt kartelat drejtorisë shtëpi "
+"të përdoruesit. Nëse dëshironi t’i mbani këto kartela, më mirë çaktivizoni "
+"llogarinë e përdoruesit."
#: modules/users/templates/users_update.html:59
-#, fuzzy
-#| msgid "Delete files"
msgid "Delete user and files"
-msgstr "Fshini kartela"
+msgstr "Fshini përdorues dhe kartela"
#: modules/users/templates/users_update.html:62
msgid "Cancel"
@@ -9126,10 +9125,9 @@ msgid "Edit User"
msgstr "Përpunoni Përdorues"
#: modules/users/views.py:111
-#, fuzzy, python-format
-#| msgid "User %(username)s created."
+#, python-format
msgid "User %(username)s deleted."
-msgstr "Përdoruesi %(username)s u krijua."
+msgstr "Përdoruesi %(username)s u fshi."
#: modules/users/views.py:130
msgid "Change Password"
From bfdb05bf0dde013b6845841baf4e426747b6a0ff Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Mon, 4 Nov 2024 10:11:05 -0800
Subject: [PATCH 05/25] networks: Fix editing wireless connections with SSID
field
Fixes: #2447.
- When editing an existing wireless connection, SSID field shows as "b'myap'"
instead of "myap". Fix this.
Tests:
- On a machine with a wireless connection, edit the connection. Without the
patch, form show SSID incorrectly. With the patch, it shows the correct value.
- Unit tests in test_network.py pass when run as root.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/modules/networks/views.py | 3 ++-
plinth/tests/test_network.py | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/plinth/modules/networks/views.py b/plinth/modules/networks/views.py
index 5074b796f..7ebc68700 100644
--- a/plinth/modules/networks/views.py
+++ b/plinth/modules/networks/views.py
@@ -307,7 +307,8 @@ def edit(request, uuid):
form = GenericForm(form_data)
elif settings_connection.get_connection_type() == '802-11-wireless':
settings_wireless = connection.get_setting_wireless()
- form_data['ssid'] = settings_wireless.get_ssid().get_data()
+ form_data['ssid'] = settings_wireless.get_ssid().get_data().decode(
+ )
form_data['mode'] = settings_wireless.get_mode()
form_data['band'] = settings_wireless.get_band() or 'auto'
form_data['channel'] = settings_wireless.get_channel()
diff --git a/plinth/tests/test_network.py b/plinth/tests/test_network.py
index 1c6742a6d..7ec388bee 100644
--- a/plinth/tests/test_network.py
+++ b/plinth/tests/test_network.py
@@ -239,6 +239,8 @@ def test_edit_wifi_connection(network, wifi_uuid):
settings_wireless = connection.get_setting_wireless()
assert settings_wireless.get_ssid().get_data() == b'plinthtestwifi2'
+ assert settings_wireless.get_ssid().get_data().decode(
+ ) == 'plinthtestwifi2'
assert settings_wireless.get_mode() == 'infrastructure'
wifi_sec = connection.get_setting_wireless_security()
From 7fa664d4458a96543e7d481a494d416847c4d62d Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Mon, 4 Nov 2024 10:16:12 -0800
Subject: [PATCH 06/25] networks: Fix display of mangled SSIDs when scanning
Wi-Fi networks
In the list of Wi-Fi networks shown after scanning, the SSID shows as "b'myap'"
instead of "myap". Fix this.
Tests:
- On a machine with Wi-Fi network device, scan of Wi-Fi networks. Without the
patch, incorrect SSID labels show up. With patch, SSID is correct.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/network.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plinth/network.py b/plinth/network.py
index 43dcb0399..3bb0000c8 100644
--- a/plinth/network.py
+++ b/plinth/network.py
@@ -626,7 +626,7 @@ def wifi_scan():
# this is used in the URL it will be escaped properly and
# unescaped when taken as view function's argument.
ssid = access_point.get_ssid()
- ssid_string = ssid.get_data() if ssid else ''
+ ssid_string = ssid.get_data().decode() if ssid else ''
access_points.append({
'interface_name': device.get_iface(),
'ssid': ssid_string,
From 0e59b67bbd84e81415af59a2e7c7030e862ffaa4 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Mon, 4 Nov 2024 10:27:06 -0800
Subject: [PATCH 07/25] networks: Fix display of strength and channel for Wi-Fi
connections
- Currently, strength and channel information is not shown for Wi-Fi connections
in connection information page. This is a regression related to handling SSID as
a binary string. Fix this.
- Also fix the styling to not make signal strength too prominent.
Tests:
- On a machine with Wi-Fi network device. Viewing the Wi-Fi connection
information does not signal strength and channel without patch but show with the
patch.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/modules/networks/templates/connection_show.html | 2 +-
plinth/network.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/plinth/modules/networks/templates/connection_show.html b/plinth/modules/networks/templates/connection_show.html
index 28538e5f4..9360ddbc1 100644
--- a/plinth/modules/networks/templates/connection_show.html
+++ b/plinth/modules/networks/templates/connection_show.html
@@ -152,7 +152,7 @@
{% if access_point.channel %}
{% trans "Signal strength" %}
-
+
{{ access_point.strength }}%
diff --git a/plinth/network.py b/plinth/network.py
index 3bb0000c8..bbc5f5832 100644
--- a/plinth/network.py
+++ b/plinth/network.py
@@ -183,7 +183,7 @@ def get_status_from_wifi_access_point(device, ssid):
for access_point in device.get_access_points():
if access_point and access_point.get_ssid() and \
- access_point.get_ssid().get_data() == ssid:
+ access_point.get_ssid().get_data().decode() == ssid:
status['strength'] = access_point.get_strength()
frequency = access_point.get_frequency()
status['channel'] = _get_wifi_channel_from_frequency(frequency)
From 85cf5a16c8f1159be600960d4fa8eca8c1016833 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Mon, 4 Nov 2024 10:31:18 -0800
Subject: [PATCH 08/25] networks: Improve styling of badges in the information
tables
- Make text size and weight to be regular.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
static/themes/default/css/main.css | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/static/themes/default/css/main.css b/static/themes/default/css/main.css
index c64e29717..e6d563efa 100644
--- a/static/themes/default/css/main.css
+++ b/static/themes/default/css/main.css
@@ -361,6 +361,11 @@ footer {
margin-right: 0.25rem;
}
+.list-group-two-column .list-group-item > .badge.secondary {
+ font-size: 1rem;
+ font-weight: normal;
+}
+
.list-group-two-column .list-group-item > .secondary {
margin-left: auto;
margin-top: -0.25rem;
From 3807ee4c54e7233958c0b5572c260072a97b028d Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Wed, 6 Nov 2024 11:12:15 -0800
Subject: [PATCH 09/25] tests: functional: Wait for uninstall page load before
uninstalling
- Many functional test failures in the Gitlab CI pipeline show that uninstall
form was attempted to submitted while still in the app page. After clicking on
the uninstall menu item, we are not waiting for the page to load fully. Fix this
by waiting for page load. This change is expected to fix most of the functional
tests failures in the pipeline.
Tests:
- Ran bepasty functional tests.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/tests/functional/__init__.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/plinth/tests/functional/__init__.py b/plinth/tests/functional/__init__.py
index b1060575f..40f7f7cff 100644
--- a/plinth/tests/functional/__init__.py
+++ b/plinth/tests/functional/__init__.py
@@ -424,7 +424,9 @@ def uninstall(browser, app_name):
if not uninstall_item:
pytest.skip('App cannot be uninstalled')
+ uninstall_page_url = uninstall_item[0]['href']
uninstall_item[0].click()
+ wait_for_page_update(browser, expected_url=uninstall_page_url)
submit(browser, form_class='form-uninstall')
while True:
From c5a967a1a249ed02a88521986cdee5cc1536b0fd Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Sun, 3 Nov 2024 10:01:57 -0800
Subject: [PATCH 10/25] i18n: Fix translation of FreedomBox name in various
places
Tests:
- With a locale that has translation for the 'FreedomBox' source string, check
the following locations have translated string for 'FreedomBox':
- Default backup repository label.
- Firewall app description.
- Network forms for: topology, internet connection type, and router
configuration.
- RSS-Bridge app description.
- TiddlyWiki app description.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/modules/backups/repository.py | 2 +-
plinth/modules/firewall/__init__.py | 2 +-
plinth/modules/networks/forms.py | 24 ++++++++++++------------
plinth/modules/rssbridge/__init__.py | 2 +-
plinth/modules/tiddlywiki/__init__.py | 7 +++----
5 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/plinth/modules/backups/repository.py b/plinth/modules/backups/repository.py
index 9ec67c134..614486316 100644
--- a/plinth/modules/backups/repository.py
+++ b/plinth/modules/backups/repository.py
@@ -334,7 +334,7 @@ class RootBorgRepository(BaseBorgRepository):
PATH = '/var/lib/freedombox/borgbackup'
storage_type = 'root'
- name = format_lazy(_('{box_name} storage'), box_name=cfg.box_name)
+ name = format_lazy(_('{box_name} storage'), box_name=_(cfg.box_name))
borg_path = PATH
sort_order = 10
is_mounted = True
diff --git a/plinth/modules/firewall/__init__.py b/plinth/modules/firewall/__init__.py
index 1b559fbca..fa00acb64 100644
--- a/plinth/modules/firewall/__init__.py
+++ b/plinth/modules/firewall/__init__.py
@@ -25,7 +25,7 @@ _description = [
_('Firewall is a security system that controls the incoming and '
'outgoing network traffic on your {box_name}. Keeping a '
'firewall enabled and properly configured reduces risk of '
- 'security threat from the Internet.'), box_name=cfg.box_name)
+ 'security threat from the Internet.'), box_name=_(cfg.box_name))
]
_port_details: dict[str, list[str]] = {}
diff --git a/plinth/modules/networks/forms.py b/plinth/modules/networks/forms.py
index 0067dc023..b2dc3f37f 100644
--- a/plinth/modules/networks/forms.py
+++ b/plinth/modules/networks/forms.py
@@ -364,7 +364,7 @@ class NetworkTopologyForm(forms.Form):
network_topology = forms.ChoiceField(
label=format_lazy(
_('Specify how your {box_name} is connected to your network'),
- box_name=cfg.box_name),
+ box_name=_(cfg.box_name)),
required=True,
widget=forms.RadioSelect,
choices=[
@@ -373,8 +373,8 @@ class NetworkTopologyForm(forms.Form):
_('Connected to a router '
'
Your {box_name} gets its Internet '
'connection from your router via Wi-Fi or Ethernet cable. '
- 'This is a typical home setup.
'), box_name=cfg.box_name,
- allow_markup=True)),
+ 'This is a typical home setup.
'),
+ box_name=_(cfg.box_name), allow_markup=True)),
('as_router',
format_lazy(
_('{box_name} is your router '
@@ -383,14 +383,14 @@ class NetworkTopologyForm(forms.Form):
'a Wi-Fi adapter. {box_name} is directly connected to the '
'Internet and all your devices connect to {box_name} '
'for their Internet connectivity.'),
- box_name=cfg.box_name, allow_markup=True)),
+ box_name=_(cfg.box_name), allow_markup=True)),
('direct',
format_lazy(
_('Directly connected to the Internet '
'
Your Internet connection is '
'directly attached to your {box_name} and there are no '
'other devices on the network. This can happen on '
- 'community or cloud setups.
'), box_name=cfg.box_name,
+ 'community or cloud setups.'), box_name=_(cfg.box_name),
allow_markup=True)),
],
)
@@ -430,8 +430,8 @@ class InternetConnectionTypeForm(forms.Form):
'same IP address. This is the most trouble-free setup for '
'many {box_name} services but very few ISPs offer this. '
'You may be able to get this service from your ISP by '
- 'making an additional payment.'), box_name=cfg.box_name,
- allow_markup=True)),
+ 'making an additional payment.'),
+ box_name=_(cfg.box_name), allow_markup=True)),
('private_ip',
format_lazy(
_('I dont have a public IP address'
@@ -444,7 +444,7 @@ class InternetConnectionTypeForm(forms.Form):
'most troublesome situation for hosting services at home. '
'{box_name} provides many workaround solutions but each '
'solution has some limitations.'),
- box_name=cfg.box_name, allow_markup=True)),
+ box_name=_(cfg.box_name), allow_markup=True)),
('unknown',
format_lazy(
_('I do not know the type of connection my ISP provides '
@@ -476,8 +476,8 @@ class RouterConfigurationForm(forms.Form):
'Internet to a single IP address such as the '
'{box_name}\'s IP address. First remember to configure '
'a static local IP address for your {box_name} in your '
- 'router\'s configuration.'), box_name=cfg.box_name,
- allow_markup=True),
+ 'router\'s configuration.'),
+ box_name=_(cfg.box_name), allow_markup=True),
),
('port_forwarding',
format_lazy(
@@ -491,8 +491,8 @@ class RouterConfigurationForm(forms.Form):
'web interface need you to forward traffic from ports '
'80 and 443 to work. Each of the other applications '
'will suggest which port(s) need to be forwarded '
- 'for that application to work.'), box_name=cfg.box_name,
- allow_markup=True)),
+ 'for that application to work.'),
+ box_name=_(cfg.box_name), allow_markup=True)),
('not_configured',
format_lazy(
_('Router is currently unconfigured '
diff --git a/plinth/modules/rssbridge/__init__.py b/plinth/modules/rssbridge/__init__.py
index 13bf1cca7..6a4e6aba1 100644
--- a/plinth/modules/rssbridge/__init__.py
+++ b/plinth/modules/rssbridge/__init__.py
@@ -28,7 +28,7 @@ _description = [
_('You can use RSS-Bridge with Tiny Tiny '
'RSS to follow various websites. When adding a feed, enable '
'authentication and use your {box_name} credentials.'),
- ttrss_url=reverse_lazy('ttrss:index'), box_name=cfg.box_name),
+ ttrss_url=reverse_lazy('ttrss:index'), box_name=_(cfg.box_name)),
]
diff --git a/plinth/modules/tiddlywiki/__init__.py b/plinth/modules/tiddlywiki/__init__.py
index 012064beb..5a30ebc6b 100644
--- a/plinth/modules/tiddlywiki/__init__.py
+++ b/plinth/modules/tiddlywiki/__init__.py
@@ -26,7 +26,7 @@ _description = [
'web browser. Each wiki is a self-contained HTML file stored on your'
' {box_name}. Instead of writing long wiki pages, TiddlyWiki '
'encourages you to write several short notes called Tiddlers and '
- 'link them together into a dense graph.'), box_name=cfg.box_name),
+ 'link them together into a dense graph.'), box_name=_(cfg.box_name)),
_('It is a versatile application with a wide variety of use cases - '
'non-linear notebook, website, personal knowledge base, task and project'
' management system, personal diary etc. Plugins can extend the '
@@ -41,7 +41,7 @@ _description = [
_('Wikis are not public by default, but they can be downloaded for '
'sharing or publishing. They can be edited by '
'any user on {box_name} belonging to the wiki group. '
- 'Simultaneous editing is not supported.'), box_name=cfg.box_name,
+ 'Simultaneous editing is not supported.'), box_name=_(cfg.box_name),
users_url=reverse_lazy('users:index')),
_('Create a new wiki or upload your existing wiki file to get started.')
]
@@ -66,8 +66,7 @@ class TiddlyWikiApp(app_module.App):
short_description=_('Non-linear Notebooks'),
description=_description,
manual_page='TiddlyWiki',
- clients=manifest.clients,
- tags=manifest.tags)
+ clients=manifest.clients, tags=manifest.tags)
self.add(info)
menu_item = menu.Menu('menu-tiddlywiki', info.name,
From c38127160103ce20fcb72425d693568d922da535 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Sun, 3 Nov 2024 10:07:49 -0800
Subject: [PATCH 11/25] rssbridge: Mention miniflux in app description similar
to tt-rss
Tests:
- App description appears as expected. Links work.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/modules/rssbridge/__init__.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/plinth/modules/rssbridge/__init__.py b/plinth/modules/rssbridge/__init__.py
index 6a4e6aba1..69886794e 100644
--- a/plinth/modules/rssbridge/__init__.py
+++ b/plinth/modules/rssbridge/__init__.py
@@ -25,9 +25,11 @@ _description = [
'any user belonging to the feed-reader group.'),
users_url=reverse_lazy('users:index')),
format_lazy(
- _('You can use RSS-Bridge with Tiny Tiny '
- 'RSS to follow various websites. When adding a feed, enable '
- 'authentication and use your {box_name} credentials.'),
+ _('You can use RSS-Bridge with Miniflux '
+ 'or Tiny Tiny RSS to follow various '
+ 'websites. When adding a feed, enable authentication and use your '
+ '{box_name} credentials.'),
+ miniflux_url=reverse_lazy('miniflux:index'),
ttrss_url=reverse_lazy('ttrss:index'), box_name=_(cfg.box_name)),
]
From 62d7369724816db2f4e02e6184e2b304e3364fa6 Mon Sep 17 00:00:00 2001
From: Dietmar
Date: Wed, 6 Nov 2024 17:58:53 +0000
Subject: [PATCH 12/25] Translated using Weblate (German)
Currently translated at 98.1% (1738 of 1770 strings)
---
plinth/locale/de/LC_MESSAGES/django.po | 264 ++++++++++++++-----------
1 file changed, 144 insertions(+), 120 deletions(-)
diff --git a/plinth/locale/de/LC_MESSAGES/django.po b/plinth/locale/de/LC_MESSAGES/django.po
index 57f23b6b9..fc8c1ad7a 100644
--- a/plinth/locale/de/LC_MESSAGES/django.po
+++ b/plinth/locale/de/LC_MESSAGES/django.po
@@ -10,8 +10,8 @@ msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 20:11-0500\n"
-"PO-Revision-Date: 2024-10-26 23:15+0000\n"
-"Last-Translator: Ettore Atalan \n"
+"PO-Revision-Date: 2024-11-07 15:00+0000\n"
+"Last-Translator: Dietmar \n"
"Language-Team: German \n"
"Language: de\n"
@@ -19,7 +19,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.8.2-dev\n"
+"X-Generator: Weblate 5.8.2\n"
#: config.py:103
#, python-brace-format
@@ -330,6 +330,10 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
+"Wählen Sie die Sicherungsdatei aus, die vom lokalen Computer hochgeladen "
+"werden soll. Es muss sich um eine Datei handeln, die zuvor nach einer "
+"erfolgreichen Sicherung einer {box_name} heruntergeladen wurde. Sie muss "
+"eine .tar.gz-Erweiterung haben."
#: modules/backups/forms.py:152
msgid "Repository path format incorrect."
@@ -1249,16 +1253,12 @@ msgid "Server Administration"
msgstr "Serververwaltung"
#: modules/config/__init__.py:18
-#, fuzzy
-#| msgid ""
-#| "Here you can set some general configuration options like hostname, domain "
-#| "name, webserver home page etc."
msgid ""
"Here you can set some general configuration options like webserver home page "
"etc."
msgstr ""
-"Hier können Sie einige allgemeine Konfigurationsoptionen wie Hostname, "
-"Domainname, Webserver-Homepage usw. festlegen."
+"Hier können Sie einige allgemeine Konfigurationsoptionen wie die Startseite "
+"des Webservers usw. einstellen."
#: modules/config/__init__.py:40
msgid "General Configuration"
@@ -2084,35 +2084,24 @@ msgid "XMPP"
msgstr "XMPP"
#: modules/ejabberd/templates/ejabberd.html:18
-#, fuzzy, python-format
-#| msgid ""
-#| "Your XMPP server domain is set to %(domainname)s. User IDs will "
-#| "look like username@%(domainname)s. You can setup your domain on "
-#| "the system Configure page."
+#, python-format
msgid ""
"Your XMPP server domain is set to %(domain_name)s. User IDs will look "
"like username@%(domain_name)s. You can setup your domain on the "
"system Name Services page."
msgstr ""
-"Ihre XMPP-Serverdomain ist auf %(domainname)s eingestellt. Benutzer-"
-"IDs erscheinen als username@%(domainname)s. Sie können Ihre Domain "
-"auf der Seite Systemeinstellungen "
-"konfigurieren."
+"Ihre XMPP-Serverdomain ist auf %(domain_name)s eingestellt. Benutzer-"
+"IDs erscheinen als username@%(domain_name)s. Sie können Ihre Domain "
+"auf der Seite Namen Dienste konfigurieren."
#: modules/ejabberd/templates/ejabberd.html:25
-#, fuzzy, python-format
-#| msgid ""
-#| "Your XMPP server domain is set to %(domainname)s. User IDs will "
-#| "look like username@%(domainname)s. You can setup your domain on "
-#| "the system Configure page."
+#, python-format
msgid ""
"Your XMPP server domain is not set. You can setup your domain on the system "
"Name Services page."
msgstr ""
-"Ihre XMPP-Serverdomain ist auf %(domainname)s eingestellt. Benutzer-"
-"IDs erscheinen als username@%(domainname)s. Sie können Ihre Domain "
-"auf der Seite Systemeinstellungen "
-"konfigurieren."
+"Die Domäne Ihres XMPP-Servers ist nicht festgelegt. Sie können Ihre Domäne "
+"auf der Seite Namensdienste konfigurieren."
#: modules/email/__init__.py:26
msgid ""
@@ -2244,7 +2233,7 @@ msgstr "IMAP"
#: modules/email/manifest.py:82
msgid "Spam control"
-msgstr ""
+msgstr "Spam-Kontrolle"
#: modules/email/templates/email-aliases.html:13
#: modules/email/templates/email.html:15
@@ -2311,6 +2300,10 @@ msgid ""
"a single HTML file on your {box_name}. You can use it as a personal wiki, as "
"a web notebook, or for project documentation."
msgstr ""
+"Feather Wiki ist ein Werkzeug zur Erstellung einfacher, in sich "
+"geschlossener Wikis, die jeweils in einer einzigen HTML-Datei auf Ihrer "
+"{box_name} gespeichert sind. Sie können es als persönliches Wiki, als Web-"
+"Notizbuch oder zur Projektdokumentation verwenden."
#: modules/featherwiki/__init__.py:29
msgid ""
@@ -2318,6 +2311,9 @@ msgid ""
"wiki per topic. Customize each wiki to your liking with extensions and other "
"customization options."
msgstr ""
+"Jedes Wiki ist eine kleine Datei. Sie können so viele Wikis erstellen, wie "
+"Sie möchten, z. B. ein Wiki pro Thema. Passen Sie jedes Wiki nach Ihren "
+"Wünschen mit Erweiterungen und anderen Anpassungsoptionen an."
#: modules/featherwiki/__init__.py:33
#, python-brace-format
@@ -2325,6 +2321,8 @@ msgid ""
"Feather Wiki is downloaded from {box_name} website and not from Debian. "
"Wikis need to be upgraded to newer version manually."
msgstr ""
+"Feather Wiki wird von der {box_name} Website heruntergeladen und nicht von "
+"Debian. Wikis müssen manuell auf eine neuere Version aktualisiert werden."
#: modules/featherwiki/__init__.py:37 modules/tiddlywiki/__init__.py:41
#, python-brace-format
@@ -2334,6 +2332,10 @@ msgid ""
"{box_name} belonging to the wiki group. Simultaneous editing is not "
"supported."
msgstr ""
+"Wikis sind standardmäßig nicht öffentlich, aber sie können zum Teilen oder "
+"Veröffentlichen heruntergeladen werden. Sie können von jedem Benutzer auf {box_name}, der zur Wiki-Gruppe "
+"gehört, bearbeitet werden. Gleichzeitige Bearbeitung wird nicht unterstützt."
#: modules/featherwiki/__init__.py:56 modules/ikiwiki/__init__.py:80
#: modules/tiddlywiki/__init__.py:61
@@ -2346,37 +2348,39 @@ msgstr "Feather-Wiki"
#: modules/featherwiki/__init__.py:61
msgid "Personal Notebooks"
-msgstr ""
+msgstr "Persönliche Notizbücher"
#: modules/featherwiki/forms.py:13 modules/tiddlywiki/forms.py:13
msgid "Name of the wiki file, with file extension \".html\""
-msgstr ""
+msgstr "Name der Wiki-Datei, mit Dateierweiterung „.html“"
#: modules/featherwiki/forms.py:15 modules/tiddlywiki/forms.py:15
msgid ""
"Wiki title and description can be set from within the wiki. This file name "
"is independent of the wiki title."
msgstr ""
+"Wiki-Titel und -Beschreibung können innerhalb des Wikis festgelegt werden. "
+"Dieser Dateiname ist unabhängig vom Titel des Wikis."
#: modules/featherwiki/forms.py:23 modules/tiddlywiki/forms.py:23
msgid "New name for the wiki file, with file extension \".html\""
-msgstr ""
+msgstr "Neuer Name für die Wiki-Datei, mit Dateierweiterung „.html“"
#: modules/featherwiki/forms.py:25 modules/tiddlywiki/forms.py:25
msgid "Renaming the file has no effect on the title of the wiki."
-msgstr ""
+msgstr "Die Umbenennung der Datei hat keine Auswirkung auf den Titel des Wikis."
#: modules/featherwiki/forms.py:32
msgid "A Feather Wiki file with .html file extension"
-msgstr ""
+msgstr "Eine Feather-Wiki-Datei mit der Dateierweiterung .html"
#: modules/featherwiki/forms.py:35
msgid "Feather Wiki files must be in HTML format"
-msgstr ""
+msgstr "Feather-Wiki-Dateien müssen im HTML-Format vorliegen"
#: modules/featherwiki/forms.py:37
msgid "Upload an existing Feather Wiki file from this computer."
-msgstr ""
+msgstr "Laden Sie eine bestehende Feather-Wiki-Datei von diesem Computer hoch."
#: modules/featherwiki/manifest.py:18 modules/help/templates/help_about.html:96
#: modules/ikiwiki/manifest.py:15 modules/mediawiki/__init__.py:52
@@ -2459,6 +2463,8 @@ msgid ""
"Hint: You can download a copy of this wiki from within "
"Feather Wiki before deleting it."
msgstr ""
+"Hinweis: Sie können eine Kopie dieses Wikis aus dem Feather "
+"Wiki herunterladen, bevor Sie es löschen."
#: modules/featherwiki/templates/featherwiki_delete.html:25
#: modules/tiddlywiki/templates/tiddlywiki_delete.html:25
@@ -2658,6 +2664,9 @@ msgid ""
"Automatic software update "
"runs daily by default. For the first time, manually run it now."
msgstr ""
+"Die automatische Softwareaktualisierung läuft standardmäßig täglich. Führen Sie es jetzt "
+"zum ersten Mal manuell aus."
#: modules/first_boot/templates/firstboot_complete.html:27
#: modules/upgrades/templates/upgrades_configure.html:108
@@ -2669,6 +2678,8 @@ msgstr "Jetzt aktualisieren"
msgid ""
"Review privacy options."
msgstr ""
+"Überprüfen Sie die Datenschutzoptionen."
#: modules/first_boot/templates/firstboot_complete.html:46
#, python-format
@@ -2676,12 +2687,17 @@ msgid ""
"Review and setup network "
"connections. Change the default Wi-Fi password, if applicable."
msgstr ""
+"Überprüfen und richten Sie Netzwerkverbindungen ein. Ändern Sie das Standard-Wi-Fi-Passwort, falls "
+"erforderlich."
#: modules/first_boot/templates/firstboot_complete.html:57
#, python-format
msgid ""
"Configure a domain name."
msgstr ""
+"Konfigurieren Sie einen Domainnamen."
#: modules/first_boot/templates/firstboot_complete.html:67
#, python-format
@@ -2689,6 +2705,8 @@ msgid ""
"Configure and schedule remote backups."
msgstr ""
+"Konfigurieren und planen Sie Remote Backups."
#: modules/first_boot/templates/firstboot_complete.html:78
#, python-format
@@ -2696,6 +2714,8 @@ msgid ""
"Put %(box_name)s to use by installing apps."
msgstr ""
+"Verwenden Sie %(box_name)s, indem Sie apps installieren."
#: modules/first_boot/templates/firstboot_welcome.html:29
msgid "Start Setup"
@@ -3006,11 +3026,11 @@ msgstr "Spenden"
#: modules/help/templates/help_about.html:107
msgid "Join project"
-msgstr ""
+msgstr "Dem Projekt beitreten"
#: modules/help/templates/help_about.html:111
msgid "Translate"
-msgstr ""
+msgstr "Übersetzen"
#: modules/help/templates/help_about.html:117
#, fuzzy
@@ -3331,7 +3351,7 @@ msgstr "Anonymisierungsnetzwerk"
#: modules/shadowsocks/manifest.py:19 modules/shadowsocksserver/manifest.py:18
#: modules/tor/manifest.py:60 modules/torproxy/manifest.py:57
msgid "Censorship resistance"
-msgstr ""
+msgstr "Schutz vor Zensur"
#: modules/i2p/templates/i2p.html:12
msgid "I2P Proxies and Tunnels"
@@ -3417,7 +3437,7 @@ msgstr "Admin-Konto-Passwort"
#: modules/ikiwiki/manifest.py:15 modules/wordpress/manifest.py:26
msgid "Blog"
-msgstr ""
+msgstr "Blog"
#: modules/ikiwiki/templates/ikiwiki_configure.html:12
msgid "Manage Wikis and Blogs"
@@ -3534,7 +3554,7 @@ msgstr ""
#: modules/infinoted/manifest.py:46
msgid "Collaborative editing"
-msgstr ""
+msgstr "Gemeinschaftliche Bearbeitung"
#: modules/janus/__init__.py:23
msgid "Janus is a lightweight WebRTC server."
@@ -3564,14 +3584,12 @@ msgid "Janus Video Room"
msgstr "Janus-Videoraum"
#: modules/janus/manifest.py:16
-#, fuzzy
-#| msgid "WebRTC server"
msgid "WebRTC"
-msgstr "WebRTC-Server"
+msgstr "WebRTC"
#: modules/janus/manifest.py:16
msgid "Web conference"
-msgstr ""
+msgstr "Web-Konferenz"
#: modules/janus/templates/janus_video_room.html:205
#: modules/jsxc/templates/jsxc_launch.html:117 templates/base.html:263
@@ -3595,16 +3613,14 @@ msgid "Chat Client"
msgstr "Chatclient"
#: modules/jsxc/manifest.py:16
-#, fuzzy
-#| msgid "Web Search"
msgid "Web chat"
-msgstr "Websuche"
+msgstr "Web-Chat"
#: modules/jsxc/manifest.py:16 modules/quassel/manifest.py:54
#, fuzzy
#| msgid "IRC Client"
msgid "Client"
-msgstr "IRC-Client"
+msgstr "Client"
#: modules/kiwix/__init__.py:21
msgid ""
@@ -3680,22 +3696,18 @@ msgstr ""
"sofort gelöscht, um Speicherplatz zu sparen."
#: modules/kiwix/manifest.py:23
-#, fuzzy
-#| msgid "Offline Wikipedia"
msgid "Offline reader"
-msgstr "Wikipedia offline"
+msgstr "Offline-Leser"
#: modules/kiwix/manifest.py:24
#, fuzzy
#| msgid "Archive name"
msgid "Archival"
-msgstr "Archivname"
+msgstr "Archivierung"
#: modules/kiwix/manifest.py:26
-#, fuzzy
-#| msgid "Offline Wikipedia"
msgid "Wikipedia"
-msgstr "Wikipedia offline"
+msgstr "Wikipedia"
#: modules/kiwix/templates/kiwix-add-package.html:24
#, python-format
@@ -3749,10 +3761,8 @@ msgid "Add a new content package"
msgstr "Ein neues Inhaltspaket hinzufügen"
#: modules/kiwix/views.py:76
-#, fuzzy
-#| msgid "Content package added."
msgid "Content package already exists."
-msgstr "Inhaltspaket hinzugefügt."
+msgstr "Das Inhaltspaket existiert bereits."
#: modules/kiwix/views.py:79
msgid "Failed to add content package."
@@ -3849,16 +3859,13 @@ msgid "Obtain"
msgstr "Beziehen"
#: modules/letsencrypt/templates/letsencrypt.html:112
-#, fuzzy, python-format
-#| msgid ""
-#| "No domains have been configured. Configure "
-#| "domains to be able to obtain certificates for them."
+#, python-format
msgid ""
"No domains have been configured. Configure "
"domains to be able to obtain certificates for them."
msgstr ""
"Es wurden keine Domains konfiguriert. Um Zertifikate erhalten zu können, "
-"müssen Domains konfiguriert werden."
+"müssen Domains konfiguriert werden."
#: modules/letsencrypt/views.py:40
#, python-brace-format
@@ -3984,16 +3991,12 @@ msgid "FluffyChat"
msgstr "FluffyChat"
#: modules/matrixsynapse/manifest.py:101 modules/quassel/manifest.py:54
-#, fuzzy
-#| msgid "IRC Chatroom"
msgid "Chat room"
-msgstr "IRC-Chatraum"
+msgstr "Chatraum"
#: modules/matrixsynapse/manifest.py:105
-#, fuzzy
-#| msgid "Media streaming server"
msgid "Matrix server"
-msgstr "Medien-Streaming-Server"
+msgstr "Matrix Server"
#: modules/matrixsynapse/templates/matrix-synapse-pre-setup.html:15
#: modules/miniflux/templates/miniflux.html:12
@@ -4338,10 +4341,8 @@ msgstr ""
"erleiden."
#: modules/minetest/manifest.py:49
-#, fuzzy
-#| msgid "Updated server."
msgid "Game server"
-msgstr "Aktualisierter Server."
+msgstr "Spiele Server"
#: modules/minetest/manifest.py:49
#, fuzzy
@@ -4351,7 +4352,7 @@ msgstr "Block-Sandkasten"
#: modules/minetest/manifest.py:49
msgid "Platform"
-msgstr ""
+msgstr "Plattform"
#: modules/minetest/templates/minetest.html:17 modules/networks/forms.py:105
#: modules/networks/forms.py:145
@@ -4414,24 +4415,20 @@ msgid "totem"
msgstr "Totem"
#: modules/minidlna/manifest.py:116
-#, fuzzy
-#| msgid "Simple Media Server"
msgid "Media server"
-msgstr "Einfacher Medienserver"
+msgstr "Medienserver"
#: modules/minidlna/manifest.py:116
msgid "Television"
-msgstr ""
+msgstr "Television"
#: modules/minidlna/manifest.py:116
msgid "UPnP"
-msgstr ""
+msgstr "UPnP"
#: modules/minidlna/manifest.py:116
-#, fuzzy
-#| msgid "MiniDLNA"
msgid "DLNA"
-msgstr "MiniDLNA"
+msgstr "DLNA"
#: modules/minidlna/views.py:33
msgid "Updated media directory"
@@ -4445,6 +4442,12 @@ msgid ""
"subscribe to your favorite sites and access full article contents within the "
"reader itself."
msgstr ""
+"Miniflux ist ein webbasiertes Werkzeug, das Nachrichten und Blog-Updates von "
+"verschiedenen Websites in einem zentralen, leicht zu lesenden Format "
+"zusammenfasst. Es hat eine einfache Schnittstelle und konzentriert sich auf "
+"ein ablenkungsfreies Leseerlebnis. Sie können Ihre Lieblingsseiten "
+"abonnieren und auf den kompletten Inhalt der Artikel direkt im Reader "
+"zugreifen."
#: modules/miniflux/__init__.py:23
msgid ""
@@ -4454,45 +4457,39 @@ msgid ""
"are several third-party clients as well."
msgstr ""
+"Zu den wichtigsten Funktionen gehören Tastaturkürzel für die schnelle "
+"Navigation, Volltextsuche, Filtern von Artikeln, Kategorien und Favoriten. "
+"Miniflux wahrt die Privatsphäre der Nutzer, indem es Tracker entfernt. Die "
+"primäre Schnittstelle ist webbasiert. Es gibt auch mehrere Clients von Drittanbietern."
#: modules/miniflux/__init__.py:42 modules/miniflux/manifest.py:10
msgid "Miniflux"
-msgstr ""
+msgstr "Miniflux"
#: modules/miniflux/__init__.py:44 modules/ttrss/__init__.py:51
msgid "News Feed Reader"
msgstr "Feedreader"
#: modules/miniflux/forms.py:12
-#, fuzzy
-#| msgid "Enter a valid username."
msgid "Enter a username for the user."
-msgstr "Einen gültigen Benutzernamen eingeben."
+msgstr "Geben Sie einen Namen für den Benutzer ein."
#: modules/miniflux/forms.py:16
msgid "Enter a strong password with a minimum of 6 characters."
-msgstr ""
+msgstr "Geben Sie ein sicheres Passwort mit mindestens 6 Zeichen ein."
#: modules/miniflux/forms.py:18
-#, fuzzy
-#| msgid "Updating configuration"
msgid "Password confirmation"
-msgstr "Aktualisieren der Konfiguration"
+msgstr "Bestätigung des Passworts"
#: modules/miniflux/forms.py:20
-#, fuzzy
-#| msgid ""
-#| "Enter the password for user \"{user}\" to authorize account modifications."
msgid "Enter the same password for confirmation."
-msgstr ""
-"Geben Sie das Passwort für den Benutzer „{user}“ ein, um Kontoänderungen zu "
-"autorisieren."
+msgstr "Geben Sie zur Bestätigung das gleiche Passwort ein."
#: modules/miniflux/forms.py:31
-#, fuzzy
-#| msgid "Password updated"
msgid "Passwords do not match."
-msgstr "Passwort geändert"
+msgstr "Passwörter stimmen nicht überein."
#: modules/miniflux/manifest.py:18
msgid "Fluent Reader Lite"
@@ -4502,7 +4499,7 @@ msgstr ""
#, fuzzy
#| msgid "News Feed Reader"
msgid "Fluent Reader"
-msgstr "Feedreader"
+msgstr "Fluent Reader"
#: modules/miniflux/manifest.py:46
msgid "FluxNews"
@@ -4524,7 +4521,7 @@ msgstr ""
#, fuzzy
#| msgid "Read"
msgid "Read You"
-msgstr "Lesen"
+msgstr "Read You"
#: modules/miniflux/manifest.py:106
msgid "RSS Guard"
@@ -4538,14 +4535,14 @@ msgstr "Feedreader"
#: modules/miniflux/manifest.py:138 modules/ttrss/manifest.py:55
msgid "News aggregation"
-msgstr ""
+msgstr "Aggregation von Nachrichten"
#: modules/miniflux/manifest.py:138 modules/rssbridge/manifest.py:16
#: modules/ttrss/manifest.py:55
#, fuzzy
#| msgid "SSH"
msgid "RSS"
-msgstr "SSH"
+msgstr "RSS"
#: modules/miniflux/manifest.py:138 modules/rssbridge/manifest.py:16
#: modules/ttrss/manifest.py:55
@@ -4557,6 +4554,8 @@ msgid ""
"Create an admin user to get started. Other users can be created from within "
"Miniflux."
msgstr ""
+"Erstellen Sie einen Admin-Benutzer, um zu beginnen. Weitere Benutzer können "
+"von Miniflux aus erstellt werden."
#: modules/miniflux/templates/miniflux.html:22
#: modules/miniflux/templates/miniflux.html:24
@@ -4729,6 +4728,7 @@ msgstr "Secure Shell"
#: modules/names/forms.py:21
msgid "Use DNS-over-TLS for resolving domains (global preference)"
msgstr ""
+"DNS-over-TLS für die Auflösung von Domänen verwenden (globale Präferenz)"
#: modules/names/forms.py:49
msgid "Use DNSSEC when resolving domains (global preference)"
@@ -5040,6 +5040,8 @@ msgid ""
"Link-local: Configure automatically to use an address that is only relevant "
"to this network."
msgstr ""
+"Link-local: Automatisch konfigurieren, um eine Adresse zu verwenden, die nur "
+"für dieses Netzwerk relevant ist."
#: modules/networks/forms.py:141
msgid "Ignore: Ignore this addressing method"
@@ -5851,8 +5853,9 @@ msgid "link-local"
msgstr "link-lokal"
#: modules/networks/views.py:32
+#, fuzzy
msgid "dhcp"
-msgstr ""
+msgstr "dhcp"
#: modules/networks/views.py:33
msgid "ignore"
@@ -6622,6 +6625,10 @@ msgid ""
"available. Can be disabled in most cases if network connectivity is stable "
"and reliable."
msgstr ""
+"Verwendung bekannter öffentlicher DNS-Server zur Auflösung von Domänennamen "
+"unter ungewöhnlichen Umständen, wenn keine DNS-Server bekannt sind, aber "
+"eine Internetverbindung besteht. Kann in den meisten Fällen deaktiviert "
+"werden, wenn die Netzwerkverbindung stabil und zuverlässig ist."
#: modules/privoxy/__init__.py:25
msgid ""
@@ -8251,6 +8258,11 @@ msgid ""
"several short notes called Tiddlers and link them together into a dense "
"graph."
msgstr ""
+"TiddlyWiki ist eine interaktive Anwendung, die vollständig im Webbrowser "
+"läuft. Jedes Wiki ist eine in sich geschlossene HTML-Datei, die auf Ihrer "
+"{box_name} gespeichert ist. Anstatt lange Wiki-Seiten zu schreiben, regt "
+"TiddlyWiki dazu an, mehrere kurze Notizen, so genannte Tiddlers, zu "
+"schreiben und sie zu einem kompakten Diagramm zu verknüpfen."
#: modules/tiddlywiki/__init__.py:30
msgid ""
@@ -8260,6 +8272,12 @@ msgid ""
"TiddlyWiki. Encrypting individual tiddlers or password-protecting a wiki "
"file is possible from within the application."
msgstr ""
+"Es ist eine vielseitige Anwendung mit einer Vielzahl von "
+"Einsatzmöglichkeiten - nichtlineares Notizbuch, Webseite, persönliche "
+"Wissensdatenbank, Aufgaben- und Projektmanagementsystem, persönliches "
+"Tagebuch usw. Plugins können die Funktionalität von TiddlyWiki erweitern. "
+"Das Verschlüsseln einzelner Tiddler oder das Schützen einer Wiki-Datei mit "
+"einem Passwort ist innerhalb der Anwendung möglich."
#: modules/tiddlywiki/__init__.py:37
#, python-brace-format
@@ -8267,10 +8285,14 @@ msgid ""
"TiddlyWiki is downloaded from {box_name} website and not from Debian. Wikis "
"need to be upgraded to newer version manually."
msgstr ""
+"TiddlyWiki wird von der {box_name} Website heruntergeladen und nicht von "
+"Debian. Wikis müssen manuell auf eine neuere Version aktualisiert werden."
#: modules/tiddlywiki/__init__.py:46
msgid "Create a new wiki or upload your existing wiki file to get started."
msgstr ""
+"Erstellen Sie ein neues Wiki oder laden Sie Ihre bestehende Wiki-Datei hoch, "
+"um zu starten."
#: modules/tiddlywiki/__init__.py:64 modules/tiddlywiki/manifest.py:9
msgid "TiddlyWiki"
@@ -8282,15 +8304,15 @@ msgstr ""
#: modules/tiddlywiki/forms.py:32
msgid "A TiddlyWiki file with .html file extension"
-msgstr ""
+msgstr "Eine TiddlyWiki-Datei mit der Dateierweiterung .html"
#: modules/tiddlywiki/forms.py:35
msgid "TiddlyWiki files must be in HTML format"
-msgstr ""
+msgstr "TiddlyWiki-Dateien müssen im HTML-Format vorliegen"
#: modules/tiddlywiki/forms.py:37
msgid "Upload an existing TiddlyWiki file from this computer."
-msgstr ""
+msgstr "Laden Sie eine bestehende TiddlyWiki-Datei von diesem Computer hoch."
#: modules/tiddlywiki/manifest.py:22
msgid "Journal"
@@ -8309,6 +8331,8 @@ msgid ""
"Hint: You can download a copy of this wiki from within "
"TiddlyWiki before deleting it."
msgstr ""
+"Hinweis: Sie können eine Kopie dieses Wikis aus TiddlyWiki "
+"herunterladen, bevor Sie es löschen."
#: modules/tor/__init__.py:33 modules/torproxy/__init__.py:29
msgid ""
@@ -8691,6 +8715,8 @@ msgid ""
"Automatic software update runs daily by default. For the first time, "
"manually run it now."
msgstr ""
+"Die automatische Software-Aktualisierung wird standardmäßig täglich "
+"ausgeführt. Führen Sie es jetzt zum ersten Mal manuell aus."
#: modules/upgrades/__init__.py:242
msgid "Could not start distribution update"
@@ -9009,8 +9035,6 @@ msgstr ""
"ignoriert."
#: modules/users/forms.py:252
-#, fuzzy
-#| msgid "Delete User"
msgid "Delete user"
msgstr "Benutzer löschen"
@@ -9019,12 +9043,13 @@ msgid ""
"Deleting the user account will also remove all the files related to the "
"user. Deleting files can be avoided by setting the user account as inactive."
msgstr ""
+"Beim Löschen des Benutzerkontos werden auch alle mit dem Benutzer "
+"verbundenen Dateien gelöscht. Das Löschen von Dateien kann vermieden werden, "
+"indem das Benutzerkonto als inaktiv eingestuft wird."
#: modules/users/forms.py:305
-#, fuzzy
-#| msgid "Failed to add user to group."
msgid "Failed to delete user."
-msgstr "Hinzufügen eines Benutzers zur Gruppe ist fehlgeschlagen."
+msgstr "Benutzer konnte nicht gelöscht werden."
#: modules/users/forms.py:320
msgid "Renaming LDAP user failed."
@@ -9152,10 +9177,9 @@ msgid "Save Changes"
msgstr "Änderungen speichern"
#: modules/users/templates/users_update.html:41
-#, fuzzy, python-format
-#| msgid "Delete user %(username)s permanently?"
+#, python-format
msgid "Delete user %(username)s and all the user's files?"
-msgstr "Benutzer %(username)s dauerhaft löschen?"
+msgstr "Benutzer %(username)s und alle Dateien des Benutzers löschen?"
#: modules/users/templates/users_update.html:46 templates/messages.html:11
msgid "Close"
@@ -9166,12 +9190,13 @@ msgid ""
"Deleting a user account also removes all the files user's home directory. If "
"you wish to keep these files, disable the user account instead."
msgstr ""
+"Beim Löschen eines Benutzerkontos werden auch alle Dateien aus dem Home-"
+"Verzeichnis des Benutzers entfernt. Wenn Sie diese Dateien behalten möchten, "
+"deaktivieren Sie stattdessen das Benutzerkonto."
#: modules/users/templates/users_update.html:59
-#, fuzzy
-#| msgid "Delete files"
msgid "Delete user and files"
-msgstr "Dateien löschen"
+msgstr "Benutzer und Dateien löschen"
#: modules/users/templates/users_update.html:62
msgid "Cancel"
@@ -9192,10 +9217,9 @@ msgid "Edit User"
msgstr "Benutzer bearbeiten"
#: modules/users/views.py:111
-#, fuzzy, python-format
-#| msgid "User %(username)s created."
+#, python-format
msgid "User %(username)s deleted."
-msgstr "Benutzer %(username)s angelegt."
+msgstr "Benutzer %(username)s gelöscht."
#: modules/users/views.py:130
msgid "Change Password"
From fe98e3eb69b7b19aed3d9add816d4a5ffa1e2c18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Podhoreck=C3=BD?=
Date: Wed, 6 Nov 2024 14:19:54 +0000
Subject: [PATCH 13/25] Translated using Weblate (Czech)
Currently translated at 100.0% (1770 of 1770 strings)
---
plinth/locale/cs/LC_MESSAGES/django.po | 43 ++++++++++++--------------
1 file changed, 20 insertions(+), 23 deletions(-)
diff --git a/plinth/locale/cs/LC_MESSAGES/django.po b/plinth/locale/cs/LC_MESSAGES/django.po
index 658aa7d75..ea6dfb3ac 100644
--- a/plinth/locale/cs/LC_MESSAGES/django.po
+++ b/plinth/locale/cs/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 20:11-0500\n"
-"PO-Revision-Date: 2024-10-24 15:15+0000\n"
+"PO-Revision-Date: 2024-11-07 15:00+0000\n"
"Last-Translator: Jiří Podhorecký \n"
"Language-Team: Czech \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.8.2-dev\n"
+"X-Generator: Weblate 5.8.2\n"
#: config.py:103
#, python-brace-format
@@ -322,6 +322,9 @@ msgid ""
"file previously downloaded from the result of a successful backup on a "
"{box_name}. It must have a .tar.gz extension."
msgstr ""
+"Vyberte záložní soubor, který chcete nahrát z místního počítače. Musí se "
+"jednat o soubor, který byl dříve stažen jako výsledek úspěšného zálohování "
+"na {box_name}. Musí mít příponu .tar.gz."
#: modules/backups/forms.py:152
msgid "Repository path format incorrect."
@@ -2946,8 +2949,6 @@ msgstr ""
"source package_name \" v terminálu (pomocí Cockpit nebo SSH)."
#: modules/help/templates/help_about.html:85
-#, fuzzy
-#| msgid "Learn more"
msgid "Learn"
msgstr "Více informací"
@@ -2961,17 +2962,15 @@ msgstr "Podpořit vývoj darem"
#: modules/help/templates/help_about.html:107
msgid "Join project"
-msgstr ""
+msgstr "Připojte se k projektu"
#: modules/help/templates/help_about.html:111
msgid "Translate"
-msgstr ""
+msgstr "Přeložte"
#: modules/help/templates/help_about.html:117
-#, fuzzy
-#| msgid "Get Support"
msgid "Support"
-msgstr "Získejte podporu"
+msgstr "Podpora"
#: modules/help/templates/help_about.html:121
msgid "Forum"
@@ -8834,8 +8833,6 @@ msgstr ""
"řádek. Prázdné řádky a ty, které začínají na znak # budou ignorovány."
#: modules/users/forms.py:252
-#, fuzzy
-#| msgid "Delete User"
msgid "Delete user"
msgstr "Smazat uživatele"
@@ -8844,12 +8841,13 @@ msgid ""
"Deleting the user account will also remove all the files related to the "
"user. Deleting files can be avoided by setting the user account as inactive."
msgstr ""
+"Odstraněním uživatelského účtu se odstraní také všechny soubory související "
+"s uživatelem. Odstranění souborů lze zabránit nastavením uživatelského účtu "
+"jako neaktivního."
#: modules/users/forms.py:305
-#, fuzzy
-#| msgid "Failed to add user to group."
msgid "Failed to delete user."
-msgstr "Přidání uživatele do skupiny se nezdařilo."
+msgstr "Uživatele se nepodařilo odstranit."
#: modules/users/forms.py:320
msgid "Renaming LDAP user failed."
@@ -8974,10 +8972,9 @@ msgid "Save Changes"
msgstr "Uložit změny"
#: modules/users/templates/users_update.html:41
-#, fuzzy, python-format
-#| msgid "Delete user %(username)s permanently?"
+#, python-format
msgid "Delete user %(username)s and all the user's files?"
-msgstr "Nevratně smazat uživatele %(username)s?"
+msgstr "Smazat uživatele %(username)s a všechny jeho soubory?"
#: modules/users/templates/users_update.html:46 templates/messages.html:11
msgid "Close"
@@ -8988,12 +8985,13 @@ msgid ""
"Deleting a user account also removes all the files user's home directory. If "
"you wish to keep these files, disable the user account instead."
msgstr ""
+"Odstraněním uživatelského účtu se odstraní také všechny soubory domovského "
+"adresáře uživatele. Pokud si přejete tyto soubory zachovat, zakažte raději "
+"uživatelský účet."
#: modules/users/templates/users_update.html:59
-#, fuzzy
-#| msgid "Delete files"
msgid "Delete user and files"
-msgstr "Smazat soubory"
+msgstr "Odstranit uživatele a soubory"
#: modules/users/templates/users_update.html:62
msgid "Cancel"
@@ -9014,10 +9012,9 @@ msgid "Edit User"
msgstr "Upravit uživatele"
#: modules/users/views.py:111
-#, fuzzy, python-format
-#| msgid "User %(username)s created."
+#, python-format
msgid "User %(username)s deleted."
-msgstr "Uživatel %(username)s vytvořen."
+msgstr "Uživatel %(username)s smazán."
#: modules/users/views.py:130
msgid "Change Password"
From 63ada3ee6283cc7e346494070799fe07fe360fa9 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Wed, 6 Nov 2024 12:55:31 -0800
Subject: [PATCH 14/25] tests: functional: Don't enable/disable app during
tests
- Currently, after every test we disable the app and re-enable for the next
test. The original purpose of this disabling is to make sure that an app is
disabled after test on it. So, change the scope of disabling the app to ensure
that it is only disabled once after all the tests on the app. This should
improve the run time of the tests.
Tests:
- Run functional tests on bepasty app.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/tests/functional/__init__.py | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/plinth/tests/functional/__init__.py b/plinth/tests/functional/__init__.py
index 40f7f7cff..af6a1ca8a 100644
--- a/plinth/tests/functional/__init__.py
+++ b/plinth/tests/functional/__init__.py
@@ -738,16 +738,21 @@ class BaseAppTests:
"""Install the app and set it up if needed."""
install(session_browser, self.app_name)
+ @pytest.fixture(autouse=True, scope='class', name='disable_after_tests')
+ def fixture_disable_after_tests(self, session_browser):
+ """Disable the app after running tests."""
+ yield
+ if self.disable_after_tests:
+ app_disable(session_browser, self.app_name)
+
@pytest.fixture(autouse=True, name='background')
- def fixture_background(self, session_browser):
+ def fixture_background(self, session_browser, disable_after_tests):
"""Login, install, and enable the app."""
login(session_browser)
self.install_and_setup(session_browser)
app_enable(session_browser, self.app_name)
yield
login(session_browser)
- if self.disable_after_tests:
- app_disable(session_browser, self.app_name)
def test_enable_disable(self, session_browser):
"""Test enabling and disabling the app."""
From 90fd6a71f78e96a00c0d27930b015e9a6f7e5f63 Mon Sep 17 00:00:00 2001
From: Veiko Aasa
Date: Thu, 7 Nov 2024 13:42:40 +0200
Subject: [PATCH 15/25] container: Quote arguments that contain spaces when
restoring pytest args
Adds single quotes inside single-quoted string, for example bash command
`echo ' '"'"'test'"'"' '` prints ` 'test' `.
Also:
- Remove wrong comment in the same function.
- Fix quote usages in container script.
Tested that running bepasty tests with keyword expression filter
`-k "enable_disable or uninstall` works.
Signed-off-by: Veiko Aasa
[sunil: Use shlex.quote() for quoting]
[sunil: Pipe the script 'ssh sudo bash' instead of sending argument]
[sunil: enable color always for pytest]
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Sunil Mohan Adapa
---
container | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/container b/container
index d6b5e532a..120b8c616 100755
--- a/container
+++ b/container
@@ -121,6 +121,7 @@ import os
import pathlib
import platform
import re
+import shlex
import shutil
import subprocess
import sys
@@ -245,6 +246,8 @@ export FREEDOMBOX_SAMBA_PORT=445
chmod --recursive --silent a+rw .pytest_cache/
chmod --recursive --silent a+w htmlcov
chmod --silent a+w .coverage
+
+exit 0
'''
logger = logging.getLogger(__name__)
@@ -1079,19 +1082,20 @@ def subcommand_ssh(arguments):
def subcommand_run_tests(arguments):
"""Run tests in the container."""
distribution = arguments.distribution
- pytest_args = ' '.join(arguments.pytest_args or [])
+ pytest_args_list = arguments.pytest_args or []
+ pytest_args = ' '.join((shlex.quote(arg) for arg in pytest_args_list))
+
ip_address = _wait_for(lambda: _get_ip_address(distribution))
ssh_command = _get_ssh_command(ip_address, distribution)
- # Disable cache as root has no rights to overwrite files on /freedombox
- pytest_command = f'py.test-3 {pytest_args}'
+ pytest_command = f'py.test-3 --color=yes {pytest_args}'
logger.info('Pytest command: %s', pytest_command)
test_script = SETUP_AND_RUN_TESTS_SCRIPT.format(
pytest_command=pytest_command, distribution=distribution)
- setup_and_run_command = ['sudo', 'bash', '-c', f"'{test_script}'"]
- command = ssh_command + setup_and_run_command
- os.execlp('ssh', *command)
+ command = ssh_command + ['sudo', 'bash']
+ process = subprocess.run(command, input=test_script.encode(), check=False)
+ sys.exit(process.returncode)
def subcommand_stop(arguments):
@@ -1108,11 +1112,11 @@ def subcommand_destroy(arguments):
def subcommand_update(arguments):
"""Update the disk image."""
if _is_update_required(arguments.distribution):
- logger.info("Updating...")
+ logger.info('Updating...')
_download_disk_image(arguments.distribution, arguments.hkp_client,
force=True)
else:
- logger.info("Already using the latest image")
+ logger.info('Already using the latest image')
def set_URLs():
From a32a226492a533d9b62f53f8be4dbd9c54c7edea Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Fri, 8 Nov 2024 07:58:47 -0800
Subject: [PATCH 16/25] tests: functional: Fix visit() returning prematurely
before page load
- It appears from the functional tests run in Gitlab CI pipelines that visit()
is returning before the page has loaded fully. In the screenshots for help app
test failures, we see gitweb web page.
- To fix this, wait for a proper page load in visit().
- Cleanup syntax, rename the non-existent search class, and mechanism for
matching expected URLs.
- Also refactor waiting for uninstall page in uninstall() method. Using the
wait_for_page_update() method as context processor is more accurate.
Tests:
- Run all functional tests and ensure that there are no errors in visit()
method.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Veiko Aasa
---
plinth/tests/functional/__init__.py | 47 +++++++++++++++++++++--------
1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/plinth/tests/functional/__init__.py b/plinth/tests/functional/__init__.py
index af6a1ca8a..7b109b9d8 100644
--- a/plinth/tests/functional/__init__.py
+++ b/plinth/tests/functional/__init__.py
@@ -10,6 +10,7 @@ import pathlib
import subprocess
import tempfile
import time
+import urllib.parse
import warnings
from contextlib import contextmanager
@@ -67,7 +68,8 @@ _sys_modules = [
######################
def visit(browser, path):
"""Visit a path assuming the base URL as configured."""
- browser.visit(config['DEFAULT']['url'] + path)
+ with wait_for_page_update(browser):
+ browser.visit(config['DEFAULT']['url'] + path)
def eventually(function, args=[], timeout=30):
@@ -88,7 +90,7 @@ def eventually(function, args=[], timeout=30):
return False
-class _PageLoaded():
+class _PageLoaded:
"""
Wait until a page (re)loaded.
@@ -103,9 +105,9 @@ class _PageLoaded():
self.loaded_new_page = False
def __call__(self, driver):
- is_stale = False
+ """Return if expected page has fully loaded."""
try:
- self.element.has_class('whatever_class')
+ self.element.has_class('x-non-existing-class')
# XXX: There is still another unhandled case where the webserver
# restarts after submission of a form and the browser does not switch
# to error page. It continues to wait for a response from the server
@@ -143,17 +145,35 @@ class _PageLoaded():
return False
+ # If page has not loaded fully yet, wait until it does.
is_fully_loaded = driver.execute_script(
'return document.readyState;') == 'complete'
if not is_fully_loaded:
- is_stale = False
- elif self.expected_url is None:
- is_stale = True
- else:
- if driver.url.endswith(self.expected_url):
- is_stale = True
+ return False
- return is_stale
+ # If a page has fully loaded check if it is the expected URL.
+ return self.has_expected_url_reached(driver)
+
+ # Should never reach here.
+ return False
+
+ def has_expected_url_reached(self, driver):
+ """Return if the current browser URL is the expected URL."""
+ if not self.expected_url:
+ return True # We are not expecting a specific URL, always any URL
+
+ browser_url = urllib.parse.urlparse(driver.url)
+ expected_url = urllib.parse.urlparse(self.expected_url)
+
+ if expected_url.scheme and browser_url.scheme != expected_url.scheme:
+ return False
+
+ if expected_url.netloc and browser_url.netloc != expected_url.netloc:
+ return False
+
+ browser_path = browser_url.path.rstrip('/')
+ expected_path = expected_url.path.rstrip('/')
+ return browser_path == expected_path
@contextmanager
@@ -425,8 +445,9 @@ def uninstall(browser, app_name):
pytest.skip('App cannot be uninstalled')
uninstall_page_url = uninstall_item[0]['href']
- uninstall_item[0].click()
- wait_for_page_update(browser, expected_url=uninstall_page_url)
+ with wait_for_page_update(browser, expected_url=uninstall_page_url):
+ uninstall_item[0].click()
+
submit(browser, form_class='form-uninstall')
while True:
From 064f3c6c0cd6f92b5f98dc2c482fe282bf17bf45 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Mon, 4 Nov 2024 15:41:38 -0800
Subject: [PATCH 17/25] networks: Overhaul Wi-Fi network scan page
Fixes: #1725.
- Show multiple Wi-Fi devices in separate tables so that users can pick them
understanding what they are. Also avoids some confusion related to why APs are
duplicated.
- Request scanning if the last scan time was long ago.
- Show the last scanned time.
- Refresh page in 10 seconds if scan has been requested so that the results of
scan can be shown without user explicitly refreshing the page. Show spinner when
scan has been requested and we are awaiting results.
- Refresh page every 60 seconds in other cases.
- When an SSID can't be decoded into a string, don't show it.
- Don't show hidden networks with no SSID set.
- Improve the styling for signal strength.
- Show a message when no Wi-Fi devices are present.
- Show a message when no Wi-Fi networks are found for a device.
Tests:
- Test on a machine with Wi-Fi device available.
- When page is loaded is for the first time, spinner is shown and refresh
happens in 10 seconds. After refresh if the scan has not completed, again,
spinner is shown and page is reloaded in 10 seconds. Otherwise, spinner is not
shown and page is reloaded in 60 seconds.
- Hidden networks are not shown.
- On a machine with no Wi-Fi devices, 'No Wi-Fi device detected.' message is
shown.
- Clicking on a network takes us to new Wi-Fi network connection page with
'connection name', 'network interface' and SSID filled in correctly.
Signed-off-by: Sunil Mohan Adapa
---
.../modules/networks/templates/wifi_scan.html | 60 +++++++++-----
plinth/modules/networks/views.py | 16 ++--
plinth/network.py | 81 +++++++++++++++----
3 files changed, 120 insertions(+), 37 deletions(-)
diff --git a/plinth/modules/networks/templates/wifi_scan.html b/plinth/modules/networks/templates/wifi_scan.html
index c7011e363..4fd667f2d 100644
--- a/plinth/modules/networks/templates/wifi_scan.html
+++ b/plinth/modules/networks/templates/wifi_scan.html
@@ -10,28 +10,52 @@
{{ title }}
-
-
-
- {% for access_point in access_points %}
-
-
- {% if access_point.ssid %}
-
- {{ access_point.ssid }}
-
- {% else %}
- --
- {% endif %}
-
+ {% if not device_access_points %}
+
{% trans "No Wi-Fi device detected." %}
+ {% else %}
+
+
+ {% for device in device_access_points %}
+ {% if device_access_points|length > 1 %}
+