From d9249d109b1127dc5526b04ae64b0cdb69996e6f Mon Sep 17 00:00:00 2001 From: "ljf (zamentur)" Date: Wed, 10 Apr 2024 20:34:34 +0200 Subject: [PATCH 001/116] Depreciate Yunomonitor --- apps.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps.toml b/apps.toml index 84ede6dc..1964451e 100644 --- a/apps.toml +++ b/apps.toml @@ -4287,6 +4287,8 @@ url = "https://github.com/YunoHost-Apps/yourls_ynh" [yunomonitor] added_date = 1674232499 # 2023/01/20 +antifeatures = [ "deprecated-software" ] +deprecated_date = 1672947186 # 2023/01/05 category = "system_tools" level = 8 state = "working" From e095151d2eadd1f27fc799b06fab3a01524afba8 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Wed, 10 Apr 2024 21:31:55 +0200 Subject: [PATCH 002/116] Mark OS.js as deprecated --- apps.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps.toml b/apps.toml index 1964451e..d174dec9 100644 --- a/apps.toml +++ b/apps.toml @@ -2724,7 +2724,9 @@ url = "https://github.com/YunoHost-Apps/osada_ynh" [osjs] added_date = 1674232499 # 2023/01/20 +antifeatures = [ "deprecated-software" ] category = "wat" +deprecated_date = 1712777448 # 2024/04/10 level = 8 state = "working" url = "https://github.com/YunoHost-Apps/osjs_ynh" From 820f1f0d5e1d56825fe1a99e3e43aad4097ab5c8 Mon Sep 17 00:00:00 2001 From: tituspijean <8769166+tituspijean@users.noreply.github.com> Date: Wed, 10 Apr 2024 19:32:17 +0000 Subject: [PATCH 003/116] :art: Format TOML with Taplo --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index d174dec9..80e7d1e4 100644 --- a/apps.toml +++ b/apps.toml @@ -4290,8 +4290,8 @@ url = "https://github.com/YunoHost-Apps/yourls_ynh" [yunomonitor] added_date = 1674232499 # 2023/01/20 antifeatures = [ "deprecated-software" ] -deprecated_date = 1672947186 # 2023/01/05 category = "system_tools" +deprecated_date = 1672947186 # 2023/01/05 level = 8 state = "working" subtags = [ "monitoring" ] From 1e49ab3a0ae812bc48af060a5f7c8c2404520d36 Mon Sep 17 00:00:00 2001 From: Poesty Li Date: Tue, 9 Apr 2024 10:19:33 +0000 Subject: [PATCH 004/116] Translated readme-generator using Weblate (Chinese (Simplified)) Currently translated at 100.0% (39 of 39 strings) Translation: YunoHost/readme-generator Translate-URL: https://translate.yunohost.org/projects/yunohost/readme-generator/zh_Hans/ --- .../zh_Hans/LC_MESSAGES/messages.mo | Bin 5464 -> 5548 bytes .../zh_Hans/LC_MESSAGES/messages.po | 6 ++---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/readme_generator/translations/zh_Hans/LC_MESSAGES/messages.mo b/tools/readme_generator/translations/zh_Hans/LC_MESSAGES/messages.mo index a7de0ffb0074fa95fbb5530deecfa1f76eb7b2e5..4319afbb1b5df480c545eede3088c90fcb5d1ac2 100644 GIT binary patch delta 952 zcmX}rPe_w-9LMpmZn_@bY%Twr^_ZH|34)OB5_(e)fgK7251Lp+vaMQBUbd)1hi+pD z;lY~*d2x{FO@a=)Nu(WOokR$_DF_+({>-f}{PudD@jUx|f1lrPKl(mJQiYH=YgCwV zg)v=Wb`zH?`JfUWvkrWM-Izf?Zs96^#VU+>&FV0To%kBta1~$T7o5UdJRHX*9573n zubN5tVi@~y4KLw04B-J@#}j;yZ9cOIO>SU2_k{~)4S0%LK*%xU(gv^}qd1B4cnv>e z7w%zz`Ry+kn!u?stHpi{VieOjfisxLA&l^lCcck%F^yXJ9$v%)RCvd@O`|8M1akqi z8~7cS;3=*%zd5{354MT=fgMzIyQTX-xXArKyn`=zD2aKD;t1W&>wAn~0X0DlG0G;? zin}n46If4Uc}yv~U*s&0OV(aCBW>$Iy%@$Zyp4)Di@mskEW&=`Rs4;5CONDv=$ z@8Uyzhl6;8&DhgG{`%ojW>=?gQG1?6&XuhpjTYl;L8a8nP$^1wqAT%_;$<)yVKMloSgs zmJXy2pBBe);I9;(O(Yf`&1F6Y{Q>tu{HZ(jJQg31KTGCjJolgu%`KPB@q7xLUF^gQ7hzKD{wrCS0I!06&{uxk+F$fZM zBbew;LC{E74-LYdAS4EXiLIio)V75}(D(Nm4|Ct=-OJo}&pr2UM87wreiQ`W8Bs^8 zp!NF9nsGLR2NCz1UBf=Sh;MNX=P?uS2F!Bt9$v*BEXOe%$2ok2Vg5XX3A~9%_|hz8 znL)D#29kIQSFiwGtie58z!Qv;++@hClK#d8vtrywCH@on*KQ*@#lxwh1&Tl=Anx!+Ae+~(LKCQ|23TgXz@&*VJTw->yqWUn-UOE`h=u?K4z9K|HY@E0aDPPS2;MlGO;Q>Cu zSdrOnT*gv7M1A)+D&eML>dzY1N*3HF>qQdvLKAeJW&gY0B~;mTC#q?D!#h_ctk8GP zL)9!vceGH17D)GnL%U21>-^6{JJl|@m|iHMIvS_o1y%HRuQSy->n`ZVtAeV6f{l9- z;;9PhLUV1{;lO~?=fv-KwzYRXXpcLCPoF28!J%RIgTE!{8*xvv_WkZr&T;4;MbuZQ diff --git a/tools/readme_generator/translations/zh_Hans/LC_MESSAGES/messages.po b/tools/readme_generator/translations/zh_Hans/LC_MESSAGES/messages.po index cf92e005..4f77dda9 100644 --- a/tools/readme_generator/translations/zh_Hans/LC_MESSAGES/messages.po +++ b/tools/readme_generator/translations/zh_Hans/LC_MESSAGES/messages.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "POT-Creation-Date: 2024-03-31 19:33+0200\n" -"PO-Revision-Date: 2024-03-26 22:06+0000\n" +"PO-Revision-Date: 2024-04-10 06:39+0000\n" "Last-Translator: Poesty Li \n" "Language-Team: Chinese (Simplified) \n" @@ -105,7 +105,7 @@ msgstr "" "请勿手动编辑。" #: templates/README.md.j2:22 -#, fuzzy, python-format +#, python-format msgid "%(application_name)s for YunoHost" msgstr "YunoHost 的 %(application_name)s" @@ -127,8 +127,6 @@ msgid "Install %(application_name)s with YunoHost" msgstr "使用 YunoHost 安装 %(application_name)s" #: templates/README.md.j2:28 -#, fuzzy -#| msgid "Read this README is other languages." msgid "Read this README in other languages." msgstr "阅读此 README 的其它语言版本。" From 53bae5a285347784b798ad1e31aa5d91dfdc1630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Pi=C3=A9dallu?= Date: Tue, 2 Apr 2024 20:02:00 +0200 Subject: [PATCH 005/116] Add autoupdate.needs_manual_tweaks to manifest schema, unused for now. It will be used in the future to print a custom message in the autoupdate PRs, maybe even from a doc/UPDATE_PR.md file from the app's repository. --- schemas/manifest.v2.schema.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schemas/manifest.v2.schema.json b/schemas/manifest.v2.schema.json index 6f38292e..e30bedea 100644 --- a/schemas/manifest.v2.schema.json +++ b/schemas/manifest.v2.schema.json @@ -579,6 +579,10 @@ "allow_prereleases": { "type": "boolean", "description": "Allow prereleases when using strategy = latest_X_release" + }, + "needs_manual_tweaks": { + "type": "boolean", + "description": "Inform the maintainer of manual steps to make autoupdate PRs work" } } } From afda60d8355e048b0570c29987a76d9b7b6a74c4 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 5 Apr 2024 17:00:15 +0000 Subject: [PATCH 006/116] Update app levels according to CI results --- apps.toml | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/apps.toml b/apps.toml index 80e7d1e4..564e0e32 100644 --- a/apps.toml +++ b/apps.toml @@ -778,14 +778,14 @@ url = "https://github.com/YunoHost-Apps/django-fmd_ynh" [django-for-runners] added_date = 1674232499 # 2023/01/20 category = "small_utilities" -level = 6 +level = 3 state = "working" url = "https://github.com/YunoHost-Apps/django-for-runners_ynh" [django-fritzconnection] added_date = 1674232499 # 2023/01/20 category = "system_tools" -level = 3 +level = 8 state = "working" subtags = [ "network" ] url = "https://github.com/YunoHost-Apps/django-fritzconnection_ynh" @@ -1009,7 +1009,7 @@ url = "https://github.com/YunoHost-Apps/ethercalc_ynh" [etherpad] added_date = 1694300530 # 2023/09/09 category = "office" -level = 7 +level = 3 potential_alternative_to = [ "G Suite", "Google Docs", "Microsoft Office", "Microsoft Word", "Office 365" ] state = "working" subtags = [ "text" ] @@ -1246,7 +1246,7 @@ url = "https://github.com/YunoHost-Apps/galene_ynh" [galette] added_date = 1674232499 # 2023/01/20 category = "productivity_and_management" -level = 8 +level = 6 state = "working" subtags = [ "business_and_ngos" ] url = "https://github.com/YunoHost-Apps/galette_ynh" @@ -1289,7 +1289,7 @@ url = "https://github.com/YunoHost-Apps/garradin_ynh" [gemserv] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 6 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/gemserv_ynh" @@ -1485,7 +1485,7 @@ url = "https://github.com/YunoHost-Apps/haste_ynh" [hat] added_date = 1674232499 # 2023/01/20 category = "small_utilities" -level = 8 +level = 1 state = "working" url = "https://github.com/YunoHost-Apps/hat_ynh" @@ -1642,6 +1642,7 @@ url = "https://github.com/YunoHost-Apps/ihatemoney_ynh" category = "multimedia" state = "working" url = "https://github.com/YunoHost-Apps/immich_ynh" +level = 7 [incus] added_date = 1710508401 # 2024/03/15 @@ -1922,7 +1923,7 @@ url = "https://github.com/YunoHost-Apps/laverna_ynh" [leantime] added_date = 1683586765 # 2023/05/08 category = "productivity_and_management" -level = 7 +level = 8 potential_alternative_to = [ "Asana", "ClickUp", "Notion" ] state = "working" subtags = [ "task" ] @@ -2040,14 +2041,14 @@ url = "https://github.com/YunoHost-Apps/limesurvey_ynh" added_date = 1685604095 # 2023/06/01 antifeatures = [ "non-free-network" ] category = "small_utilities" -level = 7 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/lingva_ynh" [linkstack] added_date = 1683443449 # 2023/05/07 category = "publishing" -level = 7 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/linkstack_ynh" @@ -2273,7 +2274,7 @@ url = "https://github.com/YunoHost-Apps/mautrix_whatsapp_ynh" [mediawiki] added_date = 1674232499 # 2023/01/20 category = "publishing" -level = 7 +level = 8 state = "working" subtags = [ "wiki" ] url = "https://github.com/YunoHost-Apps/mediawiki_ynh" @@ -2299,6 +2300,7 @@ category = "small_utilities" state = "working" subtags = [ "pastebin" ] url = "https://github.com/YunoHost-Apps/microbin_ynh" +level = 0 [minchat] added_date = 1674232499 # 2023/01/20 @@ -2383,7 +2385,7 @@ url = "https://github.com/YunoHost-Apps/moncycle_ynh" added_date = 1674232499 # 2023/01/20 branch = "main" category = "system_tools" -level = 0 +level = 8 state = "working" subtags = [ "db" ] url = "https://github.com/YunoHost-Apps/mongo-express_ynh" @@ -2509,7 +2511,7 @@ url = "https://github.com/YunoHost-Apps/mygpo_ynh" [mytinytodo] added_date = 1674232499 # 2023/01/20 category = "productivity_and_management" -level = 6 +level = 8 state = "working" subtags = [ "task" ] url = "https://github.com/YunoHost-Apps/mytinytodo_ynh" @@ -3205,7 +3207,7 @@ url = "https://github.com/YunoHost-Apps/pyload_ynh" [pytition] added_date = 1674232499 # 2023/01/20 category = "publishing" -level = 8 +level = 2 potential_alternative_to = [ "Avaaz", "Change" ] state = "working" subtags = [ "website" ] @@ -3355,7 +3357,7 @@ url = "https://github.com/YunoHost-Apps/rocketchat_ynh" [roundcube] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 6 +level = 8 potential_alternative_to = [ "GMail", "Hotmail", "Microsoft Outlook", "Yahoo! Mail" ] state = "working" subtags = [ "email" ] @@ -3410,14 +3412,14 @@ url = "https://github.com/YunoHost-Apps/samba_ynh" [satdress] added_date = 1674232499 # 2023/01/20 category = "productivity_and_management" -level = 8 +level = 1 state = "working" url = "https://github.com/YunoHost-Apps/satdress_ynh" [scovie] added_date = 1685183203 # 2023/05/27 category = "publishing" -level = 7 +level = 8 state = "working" subtags = [ "website" ] url = "https://github.com/YunoHost-Apps/scovie_ynh" @@ -3589,7 +3591,7 @@ url = "https://github.com/YunoHost-Apps/simplex_ynh" added_date = 1685875056 # 2023/06/04 antifeatures = [ "non-free-network" ] category = "small_utilities" -level = 7 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/simplytranslate_ynh" @@ -3932,7 +3934,7 @@ url = "https://github.com/YunoHost-Apps/traccar_ynh" [tracim] added_date = 1674232499 # 2023/01/20 category = "office" -level = 7 +level = 8 potential_alternative_to = [ "Dropbox", "Google Drive", "Slack", "Trello" ] state = "working" url = "https://github.com/YunoHost-Apps/tracim_ynh" @@ -4008,7 +4010,7 @@ url = "https://github.com/YunoHost-Apps/turtl_ynh" [tvheadend] added_date = 1674232499 # 2023/01/20 category = "multimedia" -level = 6 +level = 0 state = "working" url = "https://github.com/YunoHost-Apps/tvheadend_ynh" From cf6338f9ff84696d4d7fda5cbf3411284cc55d62 Mon Sep 17 00:00:00 2001 From: yunohost-bot <14998418+yunohost-bot@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:00:29 +0000 Subject: [PATCH 007/116] :art: Format TOML with Taplo --- apps.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.toml b/apps.toml index 564e0e32..019694f6 100644 --- a/apps.toml +++ b/apps.toml @@ -1640,9 +1640,9 @@ url = "https://github.com/YunoHost-Apps/ihatemoney_ynh" [immich] category = "multimedia" +level = 7 state = "working" url = "https://github.com/YunoHost-Apps/immich_ynh" -level = 7 [incus] added_date = 1710508401 # 2024/03/15 @@ -2297,10 +2297,10 @@ url = "https://github.com/YunoHost-Apps/metabase_ynh" [microbin] category = "small_utilities" +level = 0 state = "working" subtags = [ "pastebin" ] url = "https://github.com/YunoHost-Apps/microbin_ynh" -level = 0 [minchat] added_date = 1674232499 # 2023/01/20 From a60e2732a55dc64c048d215c252514489bffd734 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Sun, 7 Apr 2024 20:21:51 +0200 Subject: [PATCH 008/116] Update apps.toml: revert hat level --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index 019694f6..0ec51a15 100644 --- a/apps.toml +++ b/apps.toml @@ -1485,7 +1485,7 @@ url = "https://github.com/YunoHost-Apps/haste_ynh" [hat] added_date = 1674232499 # 2023/01/20 category = "small_utilities" -level = 1 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/hat_ynh" From 7afe6e4590aa6d7ad375fbcf2ede54301bcf29ed Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Wed, 10 Apr 2024 20:28:18 +0200 Subject: [PATCH 009/116] Update apps.toml: revert satdress and etherpad levels --- apps.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.toml b/apps.toml index 0ec51a15..b35ab5dc 100644 --- a/apps.toml +++ b/apps.toml @@ -1009,7 +1009,7 @@ url = "https://github.com/YunoHost-Apps/ethercalc_ynh" [etherpad] added_date = 1694300530 # 2023/09/09 category = "office" -level = 3 +level = 7 potential_alternative_to = [ "G Suite", "Google Docs", "Microsoft Office", "Microsoft Word", "Office 365" ] state = "working" subtags = [ "text" ] @@ -3412,7 +3412,7 @@ url = "https://github.com/YunoHost-Apps/samba_ynh" [satdress] added_date = 1674232499 # 2023/01/20 category = "productivity_and_management" -level = 1 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/satdress_ynh" From 0dee094db0f619494fe75ec88c38dcd4c107574f Mon Sep 17 00:00:00 2001 From: tituspijean Date: Thu, 11 Apr 2024 13:30:28 +0200 Subject: [PATCH 010/116] Update apps.toml: revert django-for-runners --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index b35ab5dc..9d9600c8 100644 --- a/apps.toml +++ b/apps.toml @@ -778,7 +778,7 @@ url = "https://github.com/YunoHost-Apps/django-fmd_ynh" [django-for-runners] added_date = 1674232499 # 2023/01/20 category = "small_utilities" -level = 3 +level = 6 state = "working" url = "https://github.com/YunoHost-Apps/django-for-runners_ynh" From 69c0c97ef5b469dbcaad9403e08bfdf56691a33f Mon Sep 17 00:00:00 2001 From: tituspijean Date: Thu, 11 Apr 2024 15:09:55 +0200 Subject: [PATCH 011/116] Update apps.toml: revert pytition to level 8 --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index 9d9600c8..18e3a07d 100644 --- a/apps.toml +++ b/apps.toml @@ -3207,7 +3207,7 @@ url = "https://github.com/YunoHost-Apps/pyload_ynh" [pytition] added_date = 1674232499 # 2023/01/20 category = "publishing" -level = 2 +level = 8 potential_alternative_to = [ "Avaaz", "Change" ] state = "working" subtags = [ "website" ] From 69915bb3af1b1c73b2ba2aefc903a90f66620233 Mon Sep 17 00:00:00 2001 From: Thomas <51749973+Thovi98@users.noreply.github.com> Date: Thu, 11 Apr 2024 07:47:40 +0200 Subject: [PATCH 012/116] add workout-tracker --- apps.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps.toml b/apps.toml index 18e3a07d..a46fd99a 100644 --- a/apps.toml +++ b/apps.toml @@ -4222,6 +4222,12 @@ state = "working" subtags = [ "blog", "website" ] url = "https://github.com/YunoHost-Apps/wordpress_ynh" +[workout-tracker] +category = "small_utilities" +potential_alternative_to = [ "Strava" ] +state = "working" +url = "https://github.com/YunoHost-Apps/workout-tracker_ynh" + [writefreely] added_date = 1674232499 # 2023/01/20 category = "social_media" From 802bdd200004fb7acc923e5f1b60a5432dc7b85a Mon Sep 17 00:00:00 2001 From: root Date: Fri, 12 Apr 2024 17:00:15 +0000 Subject: [PATCH 013/116] Update app levels according to CI results --- apps.toml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/apps.toml b/apps.toml index a46fd99a..9e90b5d4 100644 --- a/apps.toml +++ b/apps.toml @@ -49,7 +49,7 @@ url = "https://github.com/YunoHost-Apps/acropolis_ynh" [actual] added_date = 1685962455 # 2023/06/05 category = "productivity_and_management" -level = 7 +level = 8 potential_alternative_to = [ "Bankin", "Budgea", "Linxo", "Microsoft Money", "Mint", "You Need A Budget" ] state = "working" subtags = [ "accounting" ] @@ -173,7 +173,7 @@ url = "https://github.com/YunoHost-Apps/audiobookshelf_ynh" [autobrr] added_date = 1681591997 # 2023/04/15 category = "multimedia" -level = 7 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/autobrr_ynh" @@ -342,7 +342,7 @@ url = "https://github.com/YunoHost-Apps/calckey_ynh" [calibreweb] added_date = 1674232499 # 2023/01/20 category = "reading" -level = 6 +level = 1 state = "working" subtags = [ "books" ] url = "https://github.com/YunoHost-Apps/calibreweb_ynh" @@ -448,7 +448,7 @@ url = "https://github.com/YunoHost-Apps/cjdns_ynh" [cloudlog] added_date = 1685981922 # 2023/06/05 category = "small_utilities" -level = 7 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/cloudlog_ynh" @@ -666,7 +666,7 @@ url = "https://github.com/YunoHost-Apps/dendrite_ynh" [dex] added_date = 1674232499 # 2023/01/20 category = "system_tools" -level = 6 +level = 2 state = "working" subtags = [ "network" ] url = "https://github.com/YunoHost-Apps/dex_ynh" @@ -770,7 +770,7 @@ url = "https://github.com/YunoHost-Apps/distbin_ynh" [django-fmd] added_date = 1674232499 # 2023/01/20 category = "iot" -level = 8 +level = 3 potential_alternative_to = [ "Googles FindMyDevice" ] state = "working" url = "https://github.com/YunoHost-Apps/django-fmd_ynh" @@ -1569,7 +1569,7 @@ url = "https://github.com/Yunohost-Apps/httpsh_ynh" [hubzilla] added_date = 1674232499 # 2023/01/20 category = "social_media" -level = 6 +level = 8 potential_alternative_to = [ "Facebook" ] state = "working" subtags = [ "microblogging" ] @@ -2297,7 +2297,7 @@ url = "https://github.com/YunoHost-Apps/metabase_ynh" [microbin] category = "small_utilities" -level = 0 +level = 7 state = "working" subtags = [ "pastebin" ] url = "https://github.com/YunoHost-Apps/microbin_ynh" @@ -3664,7 +3664,7 @@ url = "https://github.com/YunoHost-Apps/sogo_ynh" [sonarr] added_date = 1674232499 # 2023/01/20 category = "multimedia" -level = 6 +level = 8 state = "working" url = "https://github.com/YunoHost-Apps/sonarr_ynh" @@ -3770,7 +3770,7 @@ url = "https://github.com/YunoHost-Apps/svgedit_ynh" [synapse] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 6 +level = 8 potential_alternative_to = [ "Discord", "Facebook Messenger", "Signal", "Skype", "Telegram", "Whatsapp" ] state = "working" subtags = [ "chat" ] @@ -4227,6 +4227,7 @@ category = "small_utilities" potential_alternative_to = [ "Strava" ] state = "working" url = "https://github.com/YunoHost-Apps/workout-tracker_ynh" +level = 7 [writefreely] added_date = 1674232499 # 2023/01/20 @@ -4342,7 +4343,7 @@ url = "https://github.com/YunoHost-Apps/zap_ynh" added_date = 1674232499 # 2023/01/20 antifeatures = [ "replaced-by-another-app" ] category = "small_utilities" -level = 6 +level = 7 potential_alternative_to = [ "Pastebin" ] state = "working" subtags = [ "pastebin" ] From 5f9bdf2f7bd895c875e61da2d72a41573113171b Mon Sep 17 00:00:00 2001 From: yunohost-bot <14998418+yunohost-bot@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:00:31 +0000 Subject: [PATCH 014/116] :art: Format TOML with Taplo --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index 9e90b5d4..4b319152 100644 --- a/apps.toml +++ b/apps.toml @@ -4224,10 +4224,10 @@ url = "https://github.com/YunoHost-Apps/wordpress_ynh" [workout-tracker] category = "small_utilities" +level = 7 potential_alternative_to = [ "Strava" ] state = "working" url = "https://github.com/YunoHost-Apps/workout-tracker_ynh" -level = 7 [writefreely] added_date = 1674232499 # 2023/01/20 From f3dd913e8feed681bee41a329dda1eae6bdec32a Mon Sep 17 00:00:00 2001 From: OniriCorpe Date: Fri, 12 Apr 2024 19:44:34 +0200 Subject: [PATCH 015/116] Update dex level --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index 4b319152..589ec17a 100644 --- a/apps.toml +++ b/apps.toml @@ -666,7 +666,7 @@ url = "https://github.com/YunoHost-Apps/dendrite_ynh" [dex] added_date = 1674232499 # 2023/01/20 category = "system_tools" -level = 2 +level = 6 state = "working" subtags = [ "network" ] url = "https://github.com/YunoHost-Apps/dex_ynh" From dc7265823675e2ef35d5c35c6c03294a4b304320 Mon Sep 17 00:00:00 2001 From: OniriCorpe Date: Fri, 12 Apr 2024 19:59:53 +0200 Subject: [PATCH 016/116] Update calibreweb level --- apps.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.toml b/apps.toml index 589ec17a..a4bc4f0d 100644 --- a/apps.toml +++ b/apps.toml @@ -342,7 +342,7 @@ url = "https://github.com/YunoHost-Apps/calckey_ynh" [calibreweb] added_date = 1674232499 # 2023/01/20 category = "reading" -level = 1 +level = 6 state = "working" subtags = [ "books" ] url = "https://github.com/YunoHost-Apps/calibreweb_ynh" From 9af89c15f5dbfab3d50354faded7fa64908021d0 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Tue, 16 Apr 2024 23:00:09 +0200 Subject: [PATCH 017/116] Add Slskd to wishlist (#2232) --- wishlist.toml | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/wishlist.toml b/wishlist.toml index a97946cc..a7e7cab7 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -399,6 +399,13 @@ upstream = "https://github.com/mguessan/davmail" website = "http://davmail.sourceforge.net/" added_date = 1695656621 # 2023/09/25 +[decap-cms] +name = "Decap CMS" +description = "A Git-based CMS for Static Site Generators" +upstream = "https://github.com/decaporg/decap-cms" +website = "https://decapcms.org/" +added_date = 1695656621 # 2023/09/25 + [digibuzzer] name = "Digibuzzer" description = "pour jouer autour d'un buzzer connecté" @@ -1039,13 +1046,6 @@ upstream = "https://github.com/locomotivecms/engine" website = "https://www.locomotivecms.com/" added_date = 1695656621 # 2023/09/25 -[lyrion-music-server] -name = "Lyrion Music Server" -description = "A streaming audio server (formerly Logitech Mediaserver, SlimServer, SqueezeCenter, SqueezeboxServer, SliMP3)" -upstream = "https://github.com/LMS-Community/slimserver" -website = "https://lyrion.org/" -added_date = 1695656621 # 2023/09/25 - [loomio] name = "Loomio" description = "A collaborative decision making tool" @@ -1053,6 +1053,13 @@ upstream = "https://github.com/loomio/loomio/" website = "https://www.loomio.org" added_date = 1695656621 # 2023/09/25 +[lyrion-music-server] +name = "Lyrion Music Server" +description = "A streaming audio server (formerly Logitech Mediaserver, SlimServer, SqueezeCenter, SqueezeboxServer, SliMP3)" +upstream = "https://github.com/LMS-Community/slimserver" +website = "https://lyrion.org/" +added_date = 1695656621 # 2023/09/25 + [maidsafe] name = "MaidSafe" description = "The Safe Network Core. API message definitions, routing and nodes, client core api." @@ -1208,13 +1215,6 @@ upstream = "https://github.com/netbirdio/netbird" website = "https://netbird.io/" added_date = 1695656621 # 2023/09/25 -[decap-cms] -name = "Decap CMS" -description = "A Git-based CMS for Static Site Generators" -upstream = "https://github.com/decaporg/decap-cms" -website = "https://decapcms.org/" -added_date = 1695656621 # 2023/09/25 - [netrunner] name = "Netrunner" description = "A card game in a cyberpunk universe" @@ -1686,6 +1686,13 @@ upstream = "https://github.com/simple-login/app" website = "https://simplelogin.io" added_date = 1695656621 # 2023/09/25 + +[slskd] +name = "Slskd" +description = "A modern client-server application for the Soulseek file sharing network." +upstream = "https://github.com/slskd/slskd" +website = "" + [smokeping] name = "smokeping" description = "The Active Monitoring System" From 0dfd3b69a90b60044ca6922f14deddc39f0d07e6 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Fri, 19 Apr 2024 17:54:52 +0200 Subject: [PATCH 018/116] Add evcc to wishlist (#2234) * Add evcc to wishlist * Fix evcc upstream --------- Co-authored-by: tituspijean --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index a7e7cab7..12e10ad0 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -532,6 +532,13 @@ upstream = "https://github.com/etesync/server" website = "https://www.etesync.com/" added_date = 1695656621 # 2023/09/25 + +[evcc] +name = "evcc" +description = "Management system for cost optimized and solar powered EV charging" +upstream = "https://github.com/evcc-io/evcc" +website = "https://evcc.io/" + [excalibur] name = "Excalibur" description = "A web interface to extract tabular data from PDFs (based on Camelot)" From 844e2d012dc4d7581f9ca0f338fc1a53d6903650 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Fri, 19 Apr 2024 17:55:42 +0200 Subject: [PATCH 019/116] Add Lobe Chat to wishlist (#2231) * Add Lobe Chat to wishlist * Fix Lobe Chat description --------- Co-authored-by: tituspijean --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index 12e10ad0..0c13209a 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -1039,6 +1039,13 @@ upstream = "https://github.com/savonet/liquidsoap" website = "https://www.liquidsoap.info/" added_date = 1695656621 # 2023/09/25 + +[lobe-chat] +name = "Lobe Chat" +description = "LLMs/AI chat framework, supports multiple local and remote AI Providers, modals (Vision/TTS) and plugin system" +upstream = "https://github.com/lobehub/lobe-chat" +website = "https://lobehub.com/" + [localai] name = "LocalAI" description = "LocalAI is the free, Open Source OpenAI alternative. Drop-in replacement API compatible w/ OpenAI." From 5ac6e02c2f8a206a88461302a31ea89591fbc9a4 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Fri, 19 Apr 2024 17:56:35 +0200 Subject: [PATCH 020/116] Add JAN to wishlist (#2230) * Add JAN to wishlist * Update wishlist.toml --------- Co-authored-by: tituspijean --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index 0c13209a..318658c1 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -891,6 +891,13 @@ upstream = "https://github.com/CorentinTh/it-tools" website = "https://it-tools.tech/" added_date = 1708461529 # 2024/02/20 + +[jan] +name = "JAN" +description = "GPT and LLM local AI models engine" +upstream = "https://github.com/janhq/jan" +website = "https://jan.ai" + [js-bin] name = "JS Bin" description = "Collaborative JavaScript Debugging App" From 3089c871d0bb54014ec2366bc7f922be6a16369b Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Fri, 19 Apr 2024 17:57:10 +0200 Subject: [PATCH 021/116] Add ollama to wishlist (#2222) * Add ollama to wishlist * Enhance Ollama description --------- Co-authored-by: tituspijean --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index 318658c1..e27d60ba 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -1285,6 +1285,13 @@ upstream = "https://github.com/ohmyform/ohmyform" website = "https://ohmyform.com/" added_date = 1695656621 # 2023/09/25 + +[ollama] +name = "ollama" +description = "Large language models (LLM) local engine" +upstream = "https://github.com/ollama/ollama" +website = "https://ollama.com/" + [omnivore] name = "Omnivore" description = "A read-it-later solution for people who like reading." From 4afaac830a63743563c2f1c616cb15ad0ce2aa1c Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Fri, 19 Apr 2024 18:00:06 +0200 Subject: [PATCH 022/116] Add Heyform to wishlist (#2218) * Add Heyform to wishlist * Enhance Heyform description --------- Co-authored-by: tituspijean --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index e27d60ba..e7ddec58 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -785,6 +785,13 @@ upstream = "https://github.com/hexojs/hexo" website = "https://hexo.io/" added_date = 1695656621 # 2023/09/25 + +[heyform] +name = "Heyform" +description = "Form builder" +upstream = "https://github.com/heyform/heyform" +website = "https://heyform.net" + [histopad] name = "HistoPad" description = "Log pads (etherpad) and archiving them in a git repository" From 5d9b4172a6933eaada80ef1b214b286c8bc03e58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:07:24 +0200 Subject: [PATCH 023/116] Bump werkzeug from 3.0.0 to 3.0.1 in /tools/app_generator (#2215) Bumps [werkzeug](https://github.com/pallets/werkzeug) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/werkzeug/compare/3.0.0...3.0.1) --- updated-dependencies: - dependency-name: werkzeug dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/app_generator/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/app_generator/requirements.txt b/tools/app_generator/requirements.txt index 00d63e4c..0422a02c 100644 --- a/tools/app_generator/requirements.txt +++ b/tools/app_generator/requirements.txt @@ -14,5 +14,5 @@ MarkupSafe==2.1.3 misaka==2.1.1 pycparser==2.21 visitor==0.1.3 -Werkzeug==3.0.0 +Werkzeug==3.0.1 WTForms==3.0.1 From 2d15532c31b9ec9cfb7c930c97705af591ce3385 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:07:46 +0200 Subject: [PATCH 024/116] Bump jinja2 from 3.1.2 to 3.1.3 in /tools/app_generator (#2216) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/app_generator/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/app_generator/requirements.txt b/tools/app_generator/requirements.txt index 0422a02c..0fc4fd67 100644 --- a/tools/app_generator/requirements.txt +++ b/tools/app_generator/requirements.txt @@ -9,7 +9,7 @@ Flask-Cors==4.0.0 Flask-Misaka==1.0.0 Flask-WTF==1.2.1 itsdangerous==2.1.2 -Jinja2==3.1.2 +Jinja2==3.1.3 MarkupSafe==2.1.3 misaka==2.1.1 pycparser==2.21 From 9620c788649cd91ad1ebe3e4a465f03c7387ae38 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 21 Apr 2024 13:59:34 +0200 Subject: [PATCH 025/116] Format Python code with Black (#2214) Co-authored-by: ericgaspar <46165813+ericgaspar@users.noreply.github.com> --- tools/app_generator/app_generator.py | 331 +++++++++++++++++---------- 1 file changed, 204 insertions(+), 127 deletions(-) diff --git a/tools/app_generator/app_generator.py b/tools/app_generator/app_generator.py index 69936821..384f1402 100644 --- a/tools/app_generator/app_generator.py +++ b/tools/app_generator/app_generator.py @@ -39,7 +39,7 @@ from wtforms.validators import ( from flask_babel import Babel from flask_babel import gettext -from flask import redirect, request, make_response # Language swap by redirecting +from flask import redirect, request, make_response # Language swap by redirecting # Markdown to HTML - for debugging purposes from misaka import Markdown, HtmlRenderer @@ -63,25 +63,26 @@ cors = CORS(app) environment = j2.Environment(loader=j2.FileSystemLoader("templates/")) # Handle translations -BABEL_TRANSLATION_DIRECTORIES='translations' +BABEL_TRANSLATION_DIRECTORIES = "translations" babel = Babel() -LANGUAGES = { - 'en': 'English', - 'fr': 'French' -} +LANGUAGES = {"en": "English", "fr": "French"} + def configure(app): babel.init_app(app, locale_selector=get_locale) - app.config['LANGUAGES'] = LANGUAGES + app.config["LANGUAGES"] = LANGUAGES + + def get_locale(): - print(request.accept_languages.best_match(app.config['LANGUAGES'].keys())) - print(request.cookies.get('lang', 'en')) - #return 'en' # to test - #return 'fr' - return request.cookies.get('lang', 'en') - #return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’ + print(request.accept_languages.best_match(app.config["LANGUAGES"].keys())) + print(request.cookies.get("lang", "en")) + # return 'en' # to test + # return 'fr' + return request.cookies.get("lang", "en") + # return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’ + configure(app) @@ -112,12 +113,11 @@ def markdown_file_to_html_string(file): ### Forms + class GeneralInfos(FlaskForm): app_id = StringField( - Markup( - gettext("Application identifier (id)") - ), + Markup(gettext("Application identifier (id)")), description=gettext("Small caps and without spaces"), validators=[DataRequired(), Regexp("[a-z_1-9]+.*(? \ -Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart''')), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + Markup( + gettext( + """Type the content of DESCRIPTION.md file.
\ +Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart""" + ) + ), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) disclaimer = TextAreaField( - gettext("Type the DISCLAIMER.md file content, which list warnings and attention points."), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + gettext( + "Type the DISCLAIMER.md file content, which list warnings and attention points." + ), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) pre_install = TextAreaField( - gettext("Type the PRE_INSTALL.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + gettext("Type the PRE_INSTALL.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) post_install = TextAreaField( - gettext("Type the POST_INSTALL.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + gettext("Type the POST_INSTALL.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) pre_upgrade = TextAreaField( - gettext("Type the PRE_UPGRADE.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + gettext("Type the PRE_UPGRADE.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) post_upgrade = TextAreaField( - gettext("Type the POST_UPGRADE.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + gettext("Type the POST_UPGRADE.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) admin = TextAreaField( - gettext("Type the ADMIN.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + gettext("Type the ADMIN.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) + class MoreAdvanced(FlaskForm): enable_change_url = BooleanField( gettext("Handle app install URL change (change_url script)"), default=True, render_kw={ - "title": gettext("Should changing the app URL be allowed ? (change_url change)") + "title": gettext( + "Should changing the app URL be allowed ? (change_url change)" + ) }, ) @@ -542,7 +580,9 @@ class MoreAdvanced(FlaskForm): gettext("Use logrotate for the app logs"), default=True, render_kw={ - "title": gettext("If the app generates logs, this option permit to handle their archival. Recommended.") + "title": gettext( + "If the app generates logs, this option permit to handle their archival. Recommended." + ) }, ) # TODO : specify custom log file @@ -551,7 +591,9 @@ class MoreAdvanced(FlaskForm): gettext("Protect the application against brute force attacks (via fail2ban)"), default=False, render_kw={ - "title": gettext("If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended.") + "title": gettext( + "If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended." + ) }, ) use_cron = BooleanField( @@ -575,14 +617,24 @@ class MoreAdvanced(FlaskForm): render_kw={ "placeholder": gettext("A regular expression"), "class": "form-control", - "title": gettext("Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)."), + "title": gettext( + "Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)." + ), }, ) ## Main form class GeneratorForm( - GeneralInfos, IntegrationInfos, UpstreamInfos, InstallQuestions, Resources, SpecificTechnology, AppConfig, Documentation, MoreAdvanced + GeneralInfos, + IntegrationInfos, + UpstreamInfos, + InstallQuestions, + Resources, + SpecificTechnology, + AppConfig, + Documentation, + MoreAdvanced, ): class Meta: @@ -590,17 +642,28 @@ class GeneratorForm( generator_mode = SelectField( gettext("Generator mode"), - description=gettext("In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum."), - choices=[("simple", gettext("Streamlined version")), ("tutorial", gettext("Tutorial version"))], + description=gettext( + "In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum." + ), + choices=[ + ("simple", gettext("Streamlined version")), + ("tutorial", gettext("Tutorial version")), + ], default="true", validators=[DataRequired()], ) submit_preview = SubmitField(gettext("Previsualise")) submit_download = SubmitField(gettext("Download the .zip")) - submit_demo = SubmitField(gettext('Fill with demo values'), render_kw={"onclick": "fillFormWithDefaultValues()", - "title": gettext("Generate a complete and functionnal minimalistic app that you can iterate from") - }) + submit_demo = SubmitField( + gettext("Fill with demo values"), + render_kw={ + "onclick": "fillFormWithDefaultValues()", + "title": gettext( + "Generate a complete and functionnal minimalistic app that you can iterate from" + ), + }, + ) #### Web pages @@ -617,13 +680,16 @@ def main_form_route(): print(main_form.errors) return render_template( - "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files={} + "index.html", + main_form=main_form, + generator_info=GENERATOR_DICT, + generated_files={}, ) if main_form.submit_preview.data: submit_mode = "preview" elif main_form.submit_demo.data: - submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue + submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue else: submit_mode = "download" @@ -634,15 +700,15 @@ def main_form_route(): self.content = None app_files = [ - AppFile("manifest", "manifest.toml"), - AppFile("tests", "tests.toml"), # TODO test this + AppFile("manifest", "manifest.toml"), + AppFile("tests", "tests.toml"), # TODO test this AppFile("_common.sh", "scripts/_common.sh"), - AppFile("install", "scripts/install"), - AppFile("remove", "scripts/remove"), - AppFile("backup", "scripts/backup"), - AppFile("restore", "scripts/restore"), - AppFile("upgrade", "scripts/upgrade"), - AppFile("nginx", "conf/nginx.conf"), + AppFile("install", "scripts/install"), + AppFile("remove", "scripts/remove"), + AppFile("backup", "scripts/backup"), + AppFile("restore", "scripts/restore"), + AppFile("upgrade", "scripts/upgrade"), + AppFile("nginx", "conf/nginx.conf"), ] if main_form.enable_change_url.data: @@ -653,7 +719,7 @@ def main_form_route(): # TODO : buggy, tries to open php.j2 # if main_form.main_technology.data == "php": - # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) + # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) if main_form.description.data: app_files.append(AppFile("DESCRIPTION", "docs/DESCRIPTION.md")) @@ -679,13 +745,17 @@ def main_form_route(): template_dir = os.path.dirname(__file__) + "/templates/" for app_file in app_files: template = open(template_dir + app_file.id + ".j2").read() - app_file.content = render_template_string(template, data=dict(request.form | GENERATOR_DICT)) - app_file.content = re.sub(r'\n\s+$', '\n', app_file.content, flags=re.M) - app_file.content = re.sub(r'\n{3,}', '\n\n', app_file.content, flags=re.M) + app_file.content = render_template_string( + template, data=dict(request.form | GENERATOR_DICT) + ) + app_file.content = re.sub(r"\n\s+$", "\n", app_file.content, flags=re.M) + app_file.content = re.sub(r"\n{3,}", "\n\n", app_file.content, flags=re.M) print(main_form.use_custom_config_file.data) if main_form.use_custom_config_file.data: - app_files.append(AppFile("appconf", "conf/" + main_form.custom_config_file.data)) + app_files.append( + AppFile("appconf", "conf/" + main_form.custom_config_file.data) + ) app_files[-1].content = main_form.custom_config_file_content.data print(main_form.custom_config_file.data) print(main_form.custom_config_file_content.data) @@ -701,19 +771,26 @@ def main_form_route(): zf.writestr(app_file.destination_path, app_file.content) f.seek(0) # Send the zip file to the user - return send_file(f, as_attachment=True, download_name=request.form["app_id"] + ".zip") + return send_file( + f, as_attachment=True, download_name=request.form["app_id"] + ".zip" + ) return render_template( - "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files=app_files, + "index.html", + main_form=main_form, + generator_info=GENERATOR_DICT, + generated_files=app_files, ) + # Localisation -@app.route('/language/') +@app.route("/language/") def set_language(language=None): - response = make_response(redirect(request.referrer or '/')) - response.set_cookie('lang', language) + response = make_response(redirect(request.referrer or "/")) + response.set_cookie("lang", language) return response + #### Running the web server if __name__ == "__main__": app.run(debug=True) From 5c99cfada16a5e4e08947b0d997da47572ff19e9 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Sun, 21 Apr 2024 14:05:58 +0200 Subject: [PATCH 026/116] Add Homepage to wishlist (#2171) --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index e7ddec58..a27a7970 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -806,6 +806,13 @@ upstream = "https://github.com/hay-kot/homebox/" website = "https://hay-kot.github.io/homebox/" added_date = 1696923283 # 2023/10/10 + +[homepage] +name = "Homepage" +description = "A highly customizable application dashboard with integrations for over 100 services" +upstream = "https://github.com/gethomepage/homepage" +website = "https://gethomepage.dev" + [hometown] name = "Hometown" description = "A Mastodon fork with local-only posting, support for more content types, and other features and tweaks." From 87bb4267295ee417221fe45ca76efbae5b9d5293 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Mon, 22 Apr 2024 19:56:04 +0200 Subject: [PATCH 027/116] Update app levels according to CI results (#2249) * Update app levels according to CI results * Update apps.toml: revert levels for grafana, halcyon, mantis, scovie --------- Co-authored-by: root Co-authored-by: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> --- apps.toml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/apps.toml b/apps.toml index a4bc4f0d..cc6980e5 100644 --- a/apps.toml +++ b/apps.toml @@ -793,7 +793,7 @@ url = "https://github.com/YunoHost-Apps/django-fritzconnection_ynh" [django_example] added_date = 1674232499 # 2023/01/20 category = "dev" -level = 8 +level = 3 state = "working" subtags = [ "programming" ] url = "https://github.com/YunoHost-Apps/django_example_ynh" @@ -1405,7 +1405,7 @@ url = "https://github.com/YunoHost-Apps/gotosocial_ynh" [grafana] added_date = 1674232499 # 2023/01/20 category = "system_tools" -level = 8 +level = 6 state = "working" subtags = [ "monitoring" ] url = "https://github.com/YunoHost-Apps/grafana_ynh" @@ -1941,7 +1941,7 @@ url = "https://github.com/YunoHost-Apps/leed_ynh" [lemmy] added_date = 1674232499 # 2023/01/20 category = "social_media" -level = 8 +level = 6 potential_alternative_to = [ "Hacker News", "Lobste.rs", "Reddit" ] state = "working" url = "https://github.com/YunoHost-Apps/lemmy_ynh" @@ -2238,7 +2238,7 @@ added_date = 1674232499 # 2023/01/20 antifeatures = [ "deprecated-software" ] category = "communication" deprecated_date = 1709661665 # 2024/03/05 -level = 6 +level = 0 potential_alternative_to = [ "Facebook Messenger" ] state = "working" subtags = [ "chat" ] @@ -2247,7 +2247,7 @@ url = "https://github.com/YunoHost-Apps/mautrix_facebook_ynh" [mautrix_signal] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 6 +level = 0 potential_alternative_to = [ "Signal" ] state = "working" subtags = [ "chat" ] @@ -2256,7 +2256,7 @@ url = "https://github.com/YunoHost-Apps/mautrix_signal_ynh" [mautrix_telegram] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 8 +level = 0 potential_alternative_to = [ "Telegram" ] state = "working" subtags = [ "chat" ] @@ -2265,7 +2265,7 @@ url = "https://github.com/YunoHost-Apps/mautrix_telegram_ynh" [mautrix_whatsapp] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 8 +level = 0 potential_alternative_to = [ "Whatsapp" ] state = "working" subtags = [ "chat" ] @@ -2400,7 +2400,7 @@ url = "https://github.com/YunoHost-Apps/monica_ynh" [monitorix] added_date = 1674232499 # 2023/01/20 category = "system_tools" -level = 6 +level = 8 state = "working" subtags = [ "monitoring" ] url = "https://github.com/YunoHost-Apps/monitorix_ynh" @@ -2729,7 +2729,7 @@ added_date = 1674232499 # 2023/01/20 antifeatures = [ "deprecated-software" ] category = "wat" deprecated_date = 1712777448 # 2024/04/10 -level = 8 +level = 7 state = "working" url = "https://github.com/YunoHost-Apps/osjs_ynh" @@ -3779,7 +3779,7 @@ url = "https://github.com/YunoHost-Apps/synapse_ynh" [synapse-admin] added_date = 1674232499 # 2023/01/20 category = "communication" -level = 8 +level = 1 state = "working" subtags = [ "chat" ] url = "https://github.com/YunoHost-Apps/synapse-admin_ynh" @@ -4055,7 +4055,7 @@ url = "https://github.com/YunoHost-Apps/unattended_upgrades_ynh" [uptime-kuma] added_date = 1674232499 # 2023/01/20 category = "system_tools" -level = 6 +level = 8 state = "working" subtags = [ "monitoring" ] url = "https://github.com/YunoHost-Apps/uptime-kuma_ynh" @@ -4121,7 +4121,7 @@ url = "https://github.com/YunoHost-Apps/watchdog_ynh" [weblate] added_date = 1674232499 # 2023/01/20 category = "dev" -level = 7 +level = 6 potential_alternative_to = [ "Locize", "Transifex" ] state = "working" url = "https://github.com/YunoHost-Apps/weblate_ynh" @@ -4370,7 +4370,7 @@ url = "https://github.com/YunoHost-Apps/zerotier_ynh" added_date = 1693093567 # 2023/08/26 antifeatures = [ "non-free-dependencies" ] category = "system_tools" -level = 7 +level = 0 state = "working" subtags = [ "network" ] url = "https://github.com/YunoHost-Apps/zeroui_ynh" From 12ada803dfc8f80e9b7eb7eaad9208f573cb6d07 Mon Sep 17 00:00:00 2001 From: YunoHost Bot Date: Tue, 23 Apr 2024 13:56:11 +0200 Subject: [PATCH 028/116] Add linkblocks to wishlist (#2248) --- wishlist.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wishlist.toml b/wishlist.toml index a27a7970..46f4f06f 100644 --- a/wishlist.toml +++ b/wishlist.toml @@ -1039,6 +1039,13 @@ upstream = "https://github.com/TheDavidDelta/lingva-translate" website = "https://lingva.ml/" added_date = 1695656621 # 2023/09/25 + +[linkblocks] +name = "linkblocks" +description = "Federated website aggregator" +upstream = "https://github.com/raffomania/linkblocks" +website = "https://linkblocks.zwielich.tech/" + [linkding] name = "Linkding" description = "Minimal, fast, and easy bookmark manager" From 1ad97d5704b233900f34c8373fe9412d70b80b7d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Tue, 23 Apr 2024 19:06:43 +0200 Subject: [PATCH 029/116] yologen: babel fixes (#2251) Co-authored-by: lapineige --- tools/app_generator/app_generator.py | 513 ++++++++++++--------------- 1 file changed, 227 insertions(+), 286 deletions(-) diff --git a/tools/app_generator/app_generator.py b/tools/app_generator/app_generator.py index 384f1402..95aa4041 100644 --- a/tools/app_generator/app_generator.py +++ b/tools/app_generator/app_generator.py @@ -37,9 +37,9 @@ from wtforms.validators import ( # Translations from flask_babel import Babel -from flask_babel import gettext +from flask_babel import gettext, lazy_gettext -from flask import redirect, request, make_response # Language swap by redirecting +from flask import redirect, request, make_response # Language swap by redirecting # Markdown to HTML - for debugging purposes from misaka import Markdown, HtmlRenderer @@ -51,7 +51,7 @@ from urllib import parse from secrets import token_urlsafe #### GLOBAL VARIABLES -YOLOGEN_VERSION = "0.9.1" +YOLOGEN_VERSION = "0.9.2.1" GENERATOR_DICT = {"GENERATOR_VERSION": YOLOGEN_VERSION} #### Create FLASK and Jinja Environments @@ -63,26 +63,32 @@ cors = CORS(app) environment = j2.Environment(loader=j2.FileSystemLoader("templates/")) # Handle translations -BABEL_TRANSLATION_DIRECTORIES = "translations" +BABEL_TRANSLATION_DIRECTORIES='translations' babel = Babel() -LANGUAGES = {"en": "English", "fr": "French"} +LANGUAGES = { + 'en': gettext('English'), + 'fr': gettext('French') +} +@app.context_processor +def inject_conf_var(): + return dict(AVAILABLE_LANGUAGES=LANGUAGES) def configure(app): babel.init_app(app, locale_selector=get_locale) - app.config["LANGUAGES"] = LANGUAGES - - + app.config['LANGUAGES'] = LANGUAGES def get_locale(): - print(request.accept_languages.best_match(app.config["LANGUAGES"].keys())) - print(request.cookies.get("lang", "en")) - # return 'en' # to test - # return 'fr' - return request.cookies.get("lang", "en") - # return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’ - + print(request.accept_languages.best_match(app.config['LANGUAGES'].keys())) + print(request.cookies.get('lang', 'en')) + #return 'en' # to test + #return 'fr' + if request.args.get('language'): + print(request.args.get('language')) + session['language'] = request.args.get('language') + return request.cookies.get('lang', 'en') + #return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’ configure(app) @@ -113,12 +119,23 @@ def markdown_file_to_html_string(file): ### Forms +# Language selector. Not used (in GeneratorForm) until it's fixed or superseeded. +# Use it in the HTML with {{ form_field(main_form.generator_language) }} +class Translations(FlaskForm): + generator_language = SelectField( + gettext("Select language"), + choices=[('none', "")]+[language for language in LANGUAGES.items()], + default=['en'], + id = 'selectLanguage' + ) class GeneralInfos(FlaskForm): app_id = StringField( - Markup(gettext("Application identifier (id)")), - description=gettext("Small caps and without spaces"), + Markup( + lazy_gettext("Application identifier (id)") + ), + description=lazy_gettext("Small caps and without spaces"), validators=[DataRequired(), Regexp("[a-z_1-9]+.*(? \ -Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart""" - ) - ), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + Markup(lazy_gettext('''Type the content of DESCRIPTION.md file.
\ +Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart''')), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) disclaimer = TextAreaField( - gettext( - "Type the DISCLAIMER.md file content, which list warnings and attention points." - ), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the DISCLAIMER.md file content, which list warnings and attention points."), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) pre_install = TextAreaField( - gettext("Type the PRE_INSTALL.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the PRE_INSTALL.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) post_install = TextAreaField( - gettext("Type the POST_INSTALL.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the POST_INSTALL.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) pre_upgrade = TextAreaField( - gettext("Type the PRE_UPGRADE.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the PRE_UPGRADE.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) post_upgrade = TextAreaField( - gettext("Type the POST_UPGRADE.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the POST_UPGRADE.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) admin = TextAreaField( - gettext("Type the ADMIN.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the ADMIN.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) - class MoreAdvanced(FlaskForm): enable_change_url = BooleanField( - gettext("Handle app install URL change (change_url script)"), + lazy_gettext("Handle app install URL change (change_url script)"), default=True, render_kw={ - "title": gettext( - "Should changing the app URL be allowed ? (change_url change)" - ) + "title": lazy_gettext("Should changing the app URL be allowed ? (change_url change)") }, ) use_logrotate = BooleanField( - gettext("Use logrotate for the app logs"), + lazy_gettext("Use logrotate for the app logs"), default=True, render_kw={ - "title": gettext( - "If the app generates logs, this option permit to handle their archival. Recommended." - ) + "title": lazy_gettext("If the app generates logs, this option permit to handle their archival. Recommended.") }, ) # TODO : specify custom log file # custom_log_file = "/var/log/$app/$app.log" "/var/log/nginx/${domain}-error.log" use_fail2ban = BooleanField( - gettext("Protect the application against brute force attacks (via fail2ban)"), + lazy_gettext("Protect the application against brute force attacks (via fail2ban)"), default=False, render_kw={ - "title": gettext( - "If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended." - ) + "title": lazy_gettext("If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended.") }, ) use_cron = BooleanField( - gettext("Add a CRON task for this application"), - description=gettext("Corresponds to some app periodic operations"), + lazy_gettext("Add a CRON task for this application"), + description=lazy_gettext("Corresponds to some app periodic operations"), default=False, ) cron_config_file = TextAreaField( - gettext("Type the CRON file content"), + lazy_gettext("Type the CRON file content"), validators=[Optional()], render_kw={ "class": "form-control", @@ -611,59 +586,38 @@ class MoreAdvanced(FlaskForm): ) fail2ban_regex = StringField( - gettext("Regular expression for fail2ban"), + lazy_gettext("Regular expression for fail2ban"), # Regex to match into the log for a failed login validators=[Optional()], render_kw={ - "placeholder": gettext("A regular expression"), + "placeholder": lazy_gettext("A regular expression"), "class": "form-control", - "title": gettext( - "Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)." - ), + "title": lazy_gettext("Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)."), }, ) ## Main form class GeneratorForm( - GeneralInfos, - IntegrationInfos, - UpstreamInfos, - InstallQuestions, - Resources, - SpecificTechnology, - AppConfig, - Documentation, - MoreAdvanced, + GeneralInfos, IntegrationInfos, UpstreamInfos, InstallQuestions, Ressources, SpecificTechnology, AppConfig, Documentation, MoreAdvanced ): class Meta: csrf = False generator_mode = SelectField( - gettext("Generator mode"), - description=gettext( - "In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum." - ), - choices=[ - ("simple", gettext("Streamlined version")), - ("tutorial", gettext("Tutorial version")), - ], + lazy_gettext("Generator mode"), + description=lazy_gettext("In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum."), + choices=[("simple", lazy_gettext("Streamlined version")), ("tutorial", lazy_gettext("Tutorial version"))], default="true", validators=[DataRequired()], ) - submit_preview = SubmitField(gettext("Previsualise")) - submit_download = SubmitField(gettext("Download the .zip")) - submit_demo = SubmitField( - gettext("Fill with demo values"), - render_kw={ - "onclick": "fillFormWithDefaultValues()", - "title": gettext( - "Generate a complete and functionnal minimalistic app that you can iterate from" - ), - }, - ) + submit_preview = SubmitField(lazy_gettext("Previsualise")) + submit_download = SubmitField(lazy_gettext("Download the .zip")) + submit_demo = SubmitField(lazy_gettext('Fill with demo values'), render_kw={"onclick": "fillFormWithDefaultValues()", + "title": lazy_gettext("Generate a complete and functionnal minimalistic app that you can iterate from") + }) #### Web pages @@ -673,6 +627,7 @@ def main_form_route(): main_form = GeneratorForm() app_files = [] + if request.method == "POST": if not main_form.validate_on_submit(): @@ -680,16 +635,13 @@ def main_form_route(): print(main_form.errors) return render_template( - "index.html", - main_form=main_form, - generator_info=GENERATOR_DICT, - generated_files={}, + "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files={} ) if main_form.submit_preview.data: submit_mode = "preview" elif main_form.submit_demo.data: - submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue + submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue else: submit_mode = "download" @@ -700,15 +652,15 @@ def main_form_route(): self.content = None app_files = [ - AppFile("manifest", "manifest.toml"), - AppFile("tests", "tests.toml"), # TODO test this + AppFile("manifest", "manifest.toml"), + AppFile("tests", "tests.toml"), # TODO test this AppFile("_common.sh", "scripts/_common.sh"), - AppFile("install", "scripts/install"), - AppFile("remove", "scripts/remove"), - AppFile("backup", "scripts/backup"), - AppFile("restore", "scripts/restore"), - AppFile("upgrade", "scripts/upgrade"), - AppFile("nginx", "conf/nginx.conf"), + AppFile("install", "scripts/install"), + AppFile("remove", "scripts/remove"), + AppFile("backup", "scripts/backup"), + AppFile("restore", "scripts/restore"), + AppFile("upgrade", "scripts/upgrade"), + AppFile("nginx", "conf/nginx.conf"), ] if main_form.enable_change_url.data: @@ -719,7 +671,7 @@ def main_form_route(): # TODO : buggy, tries to open php.j2 # if main_form.main_technology.data == "php": - # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) + # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) if main_form.description.data: app_files.append(AppFile("DESCRIPTION", "docs/DESCRIPTION.md")) @@ -745,17 +697,13 @@ def main_form_route(): template_dir = os.path.dirname(__file__) + "/templates/" for app_file in app_files: template = open(template_dir + app_file.id + ".j2").read() - app_file.content = render_template_string( - template, data=dict(request.form | GENERATOR_DICT) - ) - app_file.content = re.sub(r"\n\s+$", "\n", app_file.content, flags=re.M) - app_file.content = re.sub(r"\n{3,}", "\n\n", app_file.content, flags=re.M) + app_file.content = render_template_string(template, data=dict(request.form | GENERATOR_DICT)) + app_file.content = re.sub(r'\n\s+$', '\n', app_file.content, flags=re.M) + app_file.content = re.sub(r'\n{3,}', '\n\n', app_file.content, flags=re.M) print(main_form.use_custom_config_file.data) if main_form.use_custom_config_file.data: - app_files.append( - AppFile("appconf", "conf/" + main_form.custom_config_file.data) - ) + app_files.append(AppFile("appconf", "conf/" + main_form.custom_config_file.data)) app_files[-1].content = main_form.custom_config_file_content.data print(main_form.custom_config_file.data) print(main_form.custom_config_file_content.data) @@ -771,26 +719,19 @@ def main_form_route(): zf.writestr(app_file.destination_path, app_file.content) f.seek(0) # Send the zip file to the user - return send_file( - f, as_attachment=True, download_name=request.form["app_id"] + ".zip" - ) + return send_file(f, as_attachment=True, download_name=request.form["app_id"] + ".zip") return render_template( - "index.html", - main_form=main_form, - generator_info=GENERATOR_DICT, - generated_files=app_files, + "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files=app_files, ) - # Localisation -@app.route("/language/") +@app.route('/language/') def set_language(language=None): - response = make_response(redirect(request.referrer or "/")) - response.set_cookie("lang", language) + response = make_response(redirect(request.referrer or '/')) + response.set_cookie('lang', language) return response - #### Running the web server if __name__ == "__main__": app.run(debug=True) From 957db5114bdbf5b7c585883882a4abca6412f0d1 Mon Sep 17 00:00:00 2001 From: tituspijean Date: Tue, 23 Apr 2024 20:04:26 +0200 Subject: [PATCH 030/116] Yologen improvements for deployment (#2253) --- tools/app_generator/{app_generator.py => app.py} | 0 tools/app_generator/gunicorn.py | 14 ++++++++++++++ tools/app_generator/requirements.txt | 1 + 3 files changed, 15 insertions(+) rename tools/app_generator/{app_generator.py => app.py} (100%) create mode 100644 tools/app_generator/gunicorn.py diff --git a/tools/app_generator/app_generator.py b/tools/app_generator/app.py similarity index 100% rename from tools/app_generator/app_generator.py rename to tools/app_generator/app.py diff --git a/tools/app_generator/gunicorn.py b/tools/app_generator/gunicorn.py new file mode 100644 index 00000000..5f8cb853 --- /dev/null +++ b/tools/app_generator/gunicorn.py @@ -0,0 +1,14 @@ +import os + +install_dir = os.path.dirname(__file__) +command = f"{install_dir}/venv/bin/gunicorn" +pythonpath = install_dir +workers = 4 +user = "appgenerator" +bind = f"unix:{install_dir}/sock" +pid = "/run/gunicorn/appgenerator-pid" +errorlog = "/var/log/appgenerator/error.log" +accesslog = "/var/log/appgenerator/access.log" +access_log_format = '%({X-Real-IP}i)s %({X-Forwarded-For}i)s %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' +loglevel = "warning" +capture_output = True diff --git a/tools/app_generator/requirements.txt b/tools/app_generator/requirements.txt index 0fc4fd67..665d10bd 100644 --- a/tools/app_generator/requirements.txt +++ b/tools/app_generator/requirements.txt @@ -16,3 +16,4 @@ pycparser==2.21 visitor==0.1.3 Werkzeug==3.0.1 WTForms==3.0.1 +gunicorn==22.0.0 From c52b2aaf77a269b4926ca31a0a171ca5210dc895 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:05:53 +0200 Subject: [PATCH 031/116] Format Python code with Black (#2252) Co-authored-by: tituspijean <8769166+tituspijean@users.noreply.github.com> --- tools/app_generator/app.py | 368 +++++++++++++++++++++++-------------- 1 file changed, 228 insertions(+), 140 deletions(-) diff --git a/tools/app_generator/app.py b/tools/app_generator/app.py index 95aa4041..d3fb9c9e 100644 --- a/tools/app_generator/app.py +++ b/tools/app_generator/app.py @@ -39,7 +39,7 @@ from wtforms.validators import ( from flask_babel import Babel from flask_babel import gettext, lazy_gettext -from flask import redirect, request, make_response # Language swap by redirecting +from flask import redirect, request, make_response # Language swap by redirecting # Markdown to HTML - for debugging purposes from misaka import Markdown, HtmlRenderer @@ -63,32 +63,34 @@ cors = CORS(app) environment = j2.Environment(loader=j2.FileSystemLoader("templates/")) # Handle translations -BABEL_TRANSLATION_DIRECTORIES='translations' +BABEL_TRANSLATION_DIRECTORIES = "translations" babel = Babel() -LANGUAGES = { - 'en': gettext('English'), - 'fr': gettext('French') -} +LANGUAGES = {"en": gettext("English"), "fr": gettext("French")} + @app.context_processor def inject_conf_var(): return dict(AVAILABLE_LANGUAGES=LANGUAGES) + def configure(app): babel.init_app(app, locale_selector=get_locale) - app.config['LANGUAGES'] = LANGUAGES + app.config["LANGUAGES"] = LANGUAGES + + def get_locale(): - print(request.accept_languages.best_match(app.config['LANGUAGES'].keys())) - print(request.cookies.get('lang', 'en')) - #return 'en' # to test - #return 'fr' - if request.args.get('language'): - print(request.args.get('language')) - session['language'] = request.args.get('language') - return request.cookies.get('lang', 'en') - #return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’ + print(request.accept_languages.best_match(app.config["LANGUAGES"].keys())) + print(request.cookies.get("lang", "en")) + # return 'en' # to test + # return 'fr' + if request.args.get("language"): + print(request.args.get("language")) + session["language"] = request.args.get("language") + return request.cookies.get("lang", "en") + # return request.accept_languages.best_match(app.config['LANGUAGES'].keys()) # The result is based on the Accept-Language header. For testing purposes, you can directly return a language code, for example: return ‘de’ + configure(app) @@ -119,22 +121,22 @@ def markdown_file_to_html_string(file): ### Forms + # Language selector. Not used (in GeneratorForm) until it's fixed or superseeded. # Use it in the HTML with {{ form_field(main_form.generator_language) }} class Translations(FlaskForm): generator_language = SelectField( - gettext("Select language"), - choices=[('none', "")]+[language for language in LANGUAGES.items()], - default=['en'], - id = 'selectLanguage' + gettext("Select language"), + choices=[("none", "")] + [language for language in LANGUAGES.items()], + default=["en"], + id="selectLanguage", ) + class GeneralInfos(FlaskForm): app_id = StringField( - Markup( - lazy_gettext("Application identifier (id)") - ), + Markup(lazy_gettext("Application identifier (id)")), description=lazy_gettext("Small caps and without spaces"), validators=[DataRequired(), Regexp("[a-z_1-9]+.*(? \ -Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart''')), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + Markup( + lazy_gettext( + """Type the content of DESCRIPTION.md file.
\ +Do not give the software name at the beginning, as it will be integrated an 'Overview' subpart""" + ) + ), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) disclaimer = TextAreaField( - lazy_gettext("Type the DISCLAIMER.md file content, which list warnings and attention points."), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext( + "Type the DISCLAIMER.md file content, which list warnings and attention points." + ), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) pre_install = TextAreaField( - lazy_gettext("Type the PRE_INSTALL.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the PRE_INSTALL.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) post_install = TextAreaField( - lazy_gettext("Type the POST_INSTALL.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the POST_INSTALL.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) pre_upgrade = TextAreaField( - lazy_gettext("Type the PRE_UPGRADE.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the PRE_UPGRADE.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) post_upgrade = TextAreaField( - lazy_gettext("Type the POST_UPGRADE.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the POST_UPGRADE.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) admin = TextAreaField( - lazy_gettext("Type the ADMIN.md file content"), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, + lazy_gettext("Type the ADMIN.md file content"), + validators=[Optional()], + render_kw={ + "class": "form-control", + "spellcheck": "false", + }, ) + class MoreAdvanced(FlaskForm): enable_change_url = BooleanField( lazy_gettext("Handle app install URL change (change_url script)"), default=True, render_kw={ - "title": lazy_gettext("Should changing the app URL be allowed ? (change_url change)") + "title": lazy_gettext( + "Should changing the app URL be allowed ? (change_url change)" + ) }, ) @@ -559,16 +607,22 @@ class MoreAdvanced(FlaskForm): lazy_gettext("Use logrotate for the app logs"), default=True, render_kw={ - "title": lazy_gettext("If the app generates logs, this option permit to handle their archival. Recommended.") + "title": lazy_gettext( + "If the app generates logs, this option permit to handle their archival. Recommended." + ) }, ) # TODO : specify custom log file # custom_log_file = "/var/log/$app/$app.log" "/var/log/nginx/${domain}-error.log" use_fail2ban = BooleanField( - lazy_gettext("Protect the application against brute force attacks (via fail2ban)"), + lazy_gettext( + "Protect the application against brute force attacks (via fail2ban)" + ), default=False, render_kw={ - "title": lazy_gettext("If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended.") + "title": lazy_gettext( + "If the app generates failed connexions logs, this option allows to automatically banish the related IP after a certain number of failed password tries. Recommended." + ) }, ) use_cron = BooleanField( @@ -592,14 +646,24 @@ class MoreAdvanced(FlaskForm): render_kw={ "placeholder": lazy_gettext("A regular expression"), "class": "form-control", - "title": lazy_gettext("Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)."), + "title": lazy_gettext( + "Regular expression to check in the log file to activate failban (search for a line that indicates a credentials error)." + ), }, ) ## Main form class GeneratorForm( - GeneralInfos, IntegrationInfos, UpstreamInfos, InstallQuestions, Ressources, SpecificTechnology, AppConfig, Documentation, MoreAdvanced + GeneralInfos, + IntegrationInfos, + UpstreamInfos, + InstallQuestions, + Ressources, + SpecificTechnology, + AppConfig, + Documentation, + MoreAdvanced, ): class Meta: @@ -607,17 +671,28 @@ class GeneratorForm( generator_mode = SelectField( lazy_gettext("Generator mode"), - description=lazy_gettext("In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum."), - choices=[("simple", lazy_gettext("Streamlined version")), ("tutorial", lazy_gettext("Tutorial version"))], + description=lazy_gettext( + "In tutorial version, the generated app will contain additionnal comments to ease the understanding. In steamlined version, the generated app will only contain the necessary minimum." + ), + choices=[ + ("simple", lazy_gettext("Streamlined version")), + ("tutorial", lazy_gettext("Tutorial version")), + ], default="true", validators=[DataRequired()], ) submit_preview = SubmitField(lazy_gettext("Previsualise")) submit_download = SubmitField(lazy_gettext("Download the .zip")) - submit_demo = SubmitField(lazy_gettext('Fill with demo values'), render_kw={"onclick": "fillFormWithDefaultValues()", - "title": lazy_gettext("Generate a complete and functionnal minimalistic app that you can iterate from") - }) + submit_demo = SubmitField( + lazy_gettext("Fill with demo values"), + render_kw={ + "onclick": "fillFormWithDefaultValues()", + "title": lazy_gettext( + "Generate a complete and functionnal minimalistic app that you can iterate from" + ), + }, + ) #### Web pages @@ -627,7 +702,6 @@ def main_form_route(): main_form = GeneratorForm() app_files = [] - if request.method == "POST": if not main_form.validate_on_submit(): @@ -635,13 +709,16 @@ def main_form_route(): print(main_form.errors) return render_template( - "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files={} + "index.html", + main_form=main_form, + generator_info=GENERATOR_DICT, + generated_files={}, ) if main_form.submit_preview.data: submit_mode = "preview" elif main_form.submit_demo.data: - submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue + submit_mode = "demo" # TODO : for now this always trigger a preview. Not sure if that's an issue else: submit_mode = "download" @@ -652,15 +729,15 @@ def main_form_route(): self.content = None app_files = [ - AppFile("manifest", "manifest.toml"), - AppFile("tests", "tests.toml"), # TODO test this + AppFile("manifest", "manifest.toml"), + AppFile("tests", "tests.toml"), # TODO test this AppFile("_common.sh", "scripts/_common.sh"), - AppFile("install", "scripts/install"), - AppFile("remove", "scripts/remove"), - AppFile("backup", "scripts/backup"), - AppFile("restore", "scripts/restore"), - AppFile("upgrade", "scripts/upgrade"), - AppFile("nginx", "conf/nginx.conf"), + AppFile("install", "scripts/install"), + AppFile("remove", "scripts/remove"), + AppFile("backup", "scripts/backup"), + AppFile("restore", "scripts/restore"), + AppFile("upgrade", "scripts/upgrade"), + AppFile("nginx", "conf/nginx.conf"), ] if main_form.enable_change_url.data: @@ -671,7 +748,7 @@ def main_form_route(): # TODO : buggy, tries to open php.j2 # if main_form.main_technology.data == "php": - # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) + # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) if main_form.description.data: app_files.append(AppFile("DESCRIPTION", "docs/DESCRIPTION.md")) @@ -697,13 +774,17 @@ def main_form_route(): template_dir = os.path.dirname(__file__) + "/templates/" for app_file in app_files: template = open(template_dir + app_file.id + ".j2").read() - app_file.content = render_template_string(template, data=dict(request.form | GENERATOR_DICT)) - app_file.content = re.sub(r'\n\s+$', '\n', app_file.content, flags=re.M) - app_file.content = re.sub(r'\n{3,}', '\n\n', app_file.content, flags=re.M) + app_file.content = render_template_string( + template, data=dict(request.form | GENERATOR_DICT) + ) + app_file.content = re.sub(r"\n\s+$", "\n", app_file.content, flags=re.M) + app_file.content = re.sub(r"\n{3,}", "\n\n", app_file.content, flags=re.M) print(main_form.use_custom_config_file.data) if main_form.use_custom_config_file.data: - app_files.append(AppFile("appconf", "conf/" + main_form.custom_config_file.data)) + app_files.append( + AppFile("appconf", "conf/" + main_form.custom_config_file.data) + ) app_files[-1].content = main_form.custom_config_file_content.data print(main_form.custom_config_file.data) print(main_form.custom_config_file_content.data) @@ -719,19 +800,26 @@ def main_form_route(): zf.writestr(app_file.destination_path, app_file.content) f.seek(0) # Send the zip file to the user - return send_file(f, as_attachment=True, download_name=request.form["app_id"] + ".zip") + return send_file( + f, as_attachment=True, download_name=request.form["app_id"] + ".zip" + ) return render_template( - "index.html", main_form=main_form, generator_info=GENERATOR_DICT, generated_files=app_files, + "index.html", + main_form=main_form, + generator_info=GENERATOR_DICT, + generated_files=app_files, ) + # Localisation -@app.route('/language/') +@app.route("/language/") def set_language(language=None): - response = make_response(redirect(request.referrer or '/')) - response.set_cookie('lang', language) + response = make_response(redirect(request.referrer or "/")) + response.set_cookie("lang", language) return response + #### Running the web server if __name__ == "__main__": app.run(debug=True) From 1599c7706235e41a025abb35dfaa5433fb3c7a00 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Date: Tue, 23 Apr 2024 20:11:15 +0200 Subject: [PATCH 032/116] appgenerator: misc fixes (#2254) * appgenerator: docs -> doc * appgenerator: remove stuff related to DISCLAIMER.md which is not used in packaging v2 anymore --- tools/app_generator/app.py | 25 +++++---------------- tools/app_generator/templates/DISCLAIMER.j2 | 1 - tools/app_generator/templates/index.html | 1 - 3 files changed, 6 insertions(+), 21 deletions(-) delete mode 100644 tools/app_generator/templates/DISCLAIMER.j2 diff --git a/tools/app_generator/app.py b/tools/app_generator/app.py index d3fb9c9e..a4a204f9 100644 --- a/tools/app_generator/app.py +++ b/tools/app_generator/app.py @@ -539,16 +539,6 @@ Do not give the software name at the beginning, as it will be integrated an 'Ove "spellcheck": "false", }, ) - disclaimer = TextAreaField( - lazy_gettext( - "Type the DISCLAIMER.md file content, which list warnings and attention points." - ), - validators=[Optional()], - render_kw={ - "class": "form-control", - "spellcheck": "false", - }, - ) pre_install = TextAreaField( lazy_gettext("Type the PRE_INSTALL.md file content"), validators=[Optional()], @@ -751,25 +741,22 @@ def main_form_route(): # app_files.append(AppFile("php", "conf/extra_php-fpm.conf")) if main_form.description.data: - app_files.append(AppFile("DESCRIPTION", "docs/DESCRIPTION.md")) - - if main_form.disclaimer.data: - app_files.append(AppFile("DISCLAIMER", "docs/DISCLAIMER.md")) + app_files.append(AppFile("DESCRIPTION", "doc/DESCRIPTION.md")) if main_form.pre_install.data: - app_files.append(AppFile("PRE_INSTALL", "docs/PRE_INSTALL.md")) + app_files.append(AppFile("PRE_INSTALL", "doc/PRE_INSTALL.md")) if main_form.post_install.data: - app_files.append(AppFile("POST_INSTALL", "docs/POST_INSTALL.md")) + app_files.append(AppFile("POST_INSTALL", "doc/POST_INSTALL.md")) if main_form.pre_upgrade.data: - app_files.append(AppFile("PRE_UPGRADE", "docs/PRE_UPGRADE.md")) + app_files.append(AppFile("PRE_UPGRADE", "doc/PRE_UPGRADE.md")) if main_form.post_upgrade.data: - app_files.append(AppFile("POST_UPGRADE", "docs/POST_UPGRADE.md")) + app_files.append(AppFile("POST_UPGRADE", "doc/POST_UPGRADE.md")) if main_form.admin.data: - app_files.append(AppFile("ADMIN", "docs/ADMIN.md")) + app_files.append(AppFile("ADMIN", "doc/ADMIN.md")) template_dir = os.path.dirname(__file__) + "/templates/" for app_file in app_files: diff --git a/tools/app_generator/templates/DISCLAIMER.j2 b/tools/app_generator/templates/DISCLAIMER.j2 deleted file mode 100644 index a46cd0bb..00000000 --- a/tools/app_generator/templates/DISCLAIMER.j2 +++ /dev/null @@ -1 +0,0 @@ -This is a dummy disclaimer that will be added to the README.MD of your app. diff --git a/tools/app_generator/templates/index.html b/tools/app_generator/templates/index.html index 13f53d16..c1d74c8c 100644 --- a/tools/app_generator/templates/index.html +++ b/tools/app_generator/templates/index.html @@ -252,7 +252,6 @@ YunoHost app generator