Merge branch 'master' into support_gitlab_autoupgrade
|
@ -67,3 +67,8 @@ App packagers should *not* manually set their apps' level. The levels of all the
|
||||||
Applications with no recent activity and no active sign from maintainer may be flagged in `apps.toml` with the `package-not-maintained` antifeature tag to signify that the app is inactive and may slowly become outdated with respect to the upstream, or with respect to good packaging practices. It does **not** mean that the app is not working anymore.
|
Applications with no recent activity and no active sign from maintainer may be flagged in `apps.toml` with the `package-not-maintained` antifeature tag to signify that the app is inactive and may slowly become outdated with respect to the upstream, or with respect to good packaging practices. It does **not** mean that the app is not working anymore.
|
||||||
|
|
||||||
Feel free to contact the app group if you feel like taking over the maintenance of a currently unmaintained app!
|
Feel free to contact the app group if you feel like taking over the maintenance of a currently unmaintained app!
|
||||||
|
|
||||||
|
### `graveyard.toml`
|
||||||
|
|
||||||
|
This file is for apps that are long-term not-working and unlikely to be ever revived
|
||||||
|
|
||||||
|
|
257
graveyard.toml
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
[anfora]
|
||||||
|
category = "social_media"
|
||||||
|
subtags = [ "pictures" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/anfora_ynh"
|
||||||
|
|
||||||
|
[bibliogram]
|
||||||
|
category = "social_media"
|
||||||
|
potential_alternative_to = [ "Instagram" ]
|
||||||
|
subtags = [ "pictures" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/bibliogram_ynh"
|
||||||
|
|
||||||
|
[democracyos]
|
||||||
|
category = "communication"
|
||||||
|
subtags = [ "forum" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/democracyos_ynh"
|
||||||
|
|
||||||
|
[dockerui]
|
||||||
|
category = "system_tools"
|
||||||
|
url = "https://github.com/YunoHost-Apps/dockerui_ynh"
|
||||||
|
|
||||||
|
[dynette]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/dynette_ynh"
|
||||||
|
|
||||||
|
[ecko]
|
||||||
|
category = "social_media"
|
||||||
|
subtags = [ "microblogging" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/ecko_ynh"
|
||||||
|
|
||||||
|
[fallback]
|
||||||
|
category = "system_tools"
|
||||||
|
subtags = [ "backup" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/fallback_ynh"
|
||||||
|
|
||||||
|
[flask]
|
||||||
|
category = "dev"
|
||||||
|
subtags = [ "skeleton" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/flask_ynh"
|
||||||
|
|
||||||
|
[flusio]
|
||||||
|
category = "reading"
|
||||||
|
subtags = [ "rssreader" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/flusio_ynh"
|
||||||
|
|
||||||
|
[foodsoft]
|
||||||
|
category = "productivity_and_management"
|
||||||
|
subtags = [ "business_and_ngos" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/foodsoft_ynh"
|
||||||
|
|
||||||
|
[framaestro]
|
||||||
|
category = "communication"
|
||||||
|
subtags = [ "meeting" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/framaestro_ynh"
|
||||||
|
|
||||||
|
[framaestro_hub]
|
||||||
|
category = "communication"
|
||||||
|
subtags = [ "meeting" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/framaestro_hub_ynh"
|
||||||
|
|
||||||
|
[freeboard]
|
||||||
|
category = "iot"
|
||||||
|
url = "https://github.com/YunoHost-Apps/freeboard_ynh"
|
||||||
|
|
||||||
|
[freepbx]
|
||||||
|
category = "communication"
|
||||||
|
url = "https://github.com/YunoHost-Apps/freepbx_ynh"
|
||||||
|
|
||||||
|
[ftp_webapp]
|
||||||
|
category = "small_utilities"
|
||||||
|
url = "https://github.com/YunoHost-Apps/ftp_support_webapp_ynh"
|
||||||
|
|
||||||
|
[ftssolr]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/ftssolr_ynh"
|
||||||
|
|
||||||
|
[gekko]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/gekko_ynh"
|
||||||
|
|
||||||
|
[gitrepositories]
|
||||||
|
category = "dev"
|
||||||
|
subtags = [ "forge" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/gitrepositories_ynh"
|
||||||
|
|
||||||
|
[gnusocial]
|
||||||
|
category = "social_media"
|
||||||
|
potential_alternative_to = [ "X" ]
|
||||||
|
subtags = [ "microblogging" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/gnusocial_ynh"
|
||||||
|
|
||||||
|
[gogswebhost]
|
||||||
|
category = "publishing"
|
||||||
|
url = "https://github.com/YunoHost-Apps/gogs_webhost_ynh"
|
||||||
|
|
||||||
|
[internetarchive]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/internetarchive_ynh"
|
||||||
|
|
||||||
|
[jappix_mini]
|
||||||
|
category = "communication"
|
||||||
|
subtags = [ "chat" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/jappix_mini_ynh"
|
||||||
|
|
||||||
|
[lbcalerte]
|
||||||
|
category = "small_utilities"
|
||||||
|
url = "https://github.com/YunoHost-Apps/lbcalerte_ynh"
|
||||||
|
|
||||||
|
[lektor]
|
||||||
|
category = "publishing"
|
||||||
|
subtags = [ "website" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/lektor_ynh"
|
||||||
|
|
||||||
|
[mailman]
|
||||||
|
category = "communication"
|
||||||
|
potential_alternative_to = [ "Google Groups" ]
|
||||||
|
subtags = [ "email" ]
|
||||||
|
url = "https://github.com/yunohost-apps/mailman_ynh"
|
||||||
|
|
||||||
|
[mediadrop]
|
||||||
|
category = "multimedia"
|
||||||
|
subtags = [ "mediacenter" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/mediadrop_ynh"
|
||||||
|
|
||||||
|
[menu]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/menu_ynh"
|
||||||
|
|
||||||
|
[modernpaste]
|
||||||
|
category = "small_utilities"
|
||||||
|
subtags = [ "pastebin" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/modernpaste_ynh"
|
||||||
|
|
||||||
|
[monit]
|
||||||
|
category = "system_tools"
|
||||||
|
subtags = [ "monitoring" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/monit_ynh"
|
||||||
|
|
||||||
|
[multi_webapp]
|
||||||
|
category = "publishing"
|
||||||
|
subtags = [ "website" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/multi_webapp_ynh"
|
||||||
|
|
||||||
|
[munin]
|
||||||
|
category = "system_tools"
|
||||||
|
subtags = [ "monitoring" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/munin_ynh"
|
||||||
|
|
||||||
|
[nexusoss]
|
||||||
|
category = "dev"
|
||||||
|
url = "https://github.com/YunoHost-Apps/nexusoss_ynh"
|
||||||
|
|
||||||
|
[ntopng]
|
||||||
|
category = "system_tools"
|
||||||
|
url = "https://github.com/YunoHost-Apps/ntopng_ynh"
|
||||||
|
|
||||||
|
[osmw]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/osmw_ynh"
|
||||||
|
|
||||||
|
[peachpub]
|
||||||
|
category = "communication"
|
||||||
|
url = "https://github.com/YunoHost-Apps/peachpub_ynh"
|
||||||
|
|
||||||
|
[piratebox]
|
||||||
|
category = "system_tools"
|
||||||
|
subtags = [ "network" ]
|
||||||
|
url = "https://github.com/labriqueinternet/piratebox_ynh"
|
||||||
|
|
||||||
|
[plonecms]
|
||||||
|
category = "publishing"
|
||||||
|
subtags = [ "website" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/plonecms_ynh"
|
||||||
|
|
||||||
|
[portainer]
|
||||||
|
category = "system_tools"
|
||||||
|
url = "https://github.com/YunoHost-Apps/portainer_ynh"
|
||||||
|
|
||||||
|
[reel2bits]
|
||||||
|
category = "social_media"
|
||||||
|
potential_alternative_to = [ "Soundcloud" ]
|
||||||
|
subtags = [ "music" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/reel2bits_ynh"
|
||||||
|
|
||||||
|
[remotestorage]
|
||||||
|
category = "small_utilities"
|
||||||
|
url = "https://github.com/YunoHost-Apps/remotestorage_ynh"
|
||||||
|
|
||||||
|
[roadiz]
|
||||||
|
category = "publishing"
|
||||||
|
subtags = [ "website" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/roadiz_ynh"
|
||||||
|
|
||||||
|
[shsd]
|
||||||
|
category = "system_tools"
|
||||||
|
subtags = [ "monitoring" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/shsd_ynh"
|
||||||
|
|
||||||
|
[sickbeard]
|
||||||
|
category = "multimedia"
|
||||||
|
subtags = [ "download" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/sickbeard_ynh"
|
||||||
|
|
||||||
|
[sickrage]
|
||||||
|
category = "multimedia"
|
||||||
|
subtags = [ "download" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/sickrage_ynh"
|
||||||
|
|
||||||
|
[sonerezh]
|
||||||
|
category = "multimedia"
|
||||||
|
subtags = [ "music" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/sonerezh_ynh"
|
||||||
|
|
||||||
|
[staticwebapp]
|
||||||
|
category = "publishing"
|
||||||
|
url = "https://github.com/YunoHost-Apps/staticwebapp_ynh"
|
||||||
|
|
||||||
|
[subscribe]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/subscribe_ynh"
|
||||||
|
|
||||||
|
[tagspaces]
|
||||||
|
category = "synchronization"
|
||||||
|
url = "https://github.com/YunoHost-Apps/tagspaces_ynh"
|
||||||
|
|
||||||
|
[telegram_chatbot]
|
||||||
|
category = "dev"
|
||||||
|
url = "https://github.com/YunoHost-Apps/telegram_chatbot_ynh"
|
||||||
|
|
||||||
|
[tes3mp]
|
||||||
|
category = "games"
|
||||||
|
url = "https://github.com/YunoHost-Apps/tes3mp_ynh"
|
||||||
|
|
||||||
|
[transpay]
|
||||||
|
category = "productivity_and_management"
|
||||||
|
url = "https://github.com/YunoHost-Apps/transpay_ynh"
|
||||||
|
|
||||||
|
[unbound]
|
||||||
|
category = "system_tools"
|
||||||
|
url = "https://github.com/YunoHost-Apps/unbound_ynh"
|
||||||
|
|
||||||
|
[vpnserver]
|
||||||
|
category = "system_tools"
|
||||||
|
subtags = [ "network" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/vpnserver_ynh"
|
||||||
|
|
||||||
|
[wildfly]
|
||||||
|
category = "dev"
|
||||||
|
url = "https://github.com/YunoHost-Apps/wildfly_ynh"
|
||||||
|
|
||||||
|
[youtube-dl-webui]
|
||||||
|
category = "multimedia"
|
||||||
|
subtags = [ "download" ]
|
||||||
|
url = "https://github.com/YunoHost-Apps/youtube-dl-webui_ynh"
|
||||||
|
|
||||||
|
[yunofav]
|
||||||
|
category = "wat"
|
||||||
|
url = "https://github.com/YunoHost-Apps/yunofav_ynh"
|
BIN
logos/diacamma.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
logos/fluffychat.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
logos/freescout.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
logos/grist.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
logos/grocy.png
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 13 KiB |
BIN
logos/joplin.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
logos/petitesannonces.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
logos/planka.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
logos/simplytranslate.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
logos/terraforming-mars.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
logos/traccar.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
logos/woodpecker.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
logos/xwiki.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
|
@ -85,7 +85,7 @@
|
||||||
"version": {
|
"version": {
|
||||||
"description": "App and package version",
|
"description": "App and package version",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"pattern": "^[0-9a-z]*([\\.-][0-9a-z]*)*~ynh[0-9]*$"
|
"pattern": "^[0-9a-z]*([\\.+-][0-9a-z]*)*~ynh[0-9]*$"
|
||||||
},
|
},
|
||||||
"description": {"$ref": "#/$defs/translated_string"},
|
"description": {"$ref": "#/$defs/translated_string"},
|
||||||
"maintainers": {
|
"maintainers": {
|
||||||
|
@ -371,7 +371,14 @@
|
||||||
},
|
},
|
||||||
"sha256": {"$ref": "#/$defs/sha256sum"},
|
"sha256": {"$ref": "#/$defs/sha256sum"},
|
||||||
"in_subdir": {
|
"in_subdir": {
|
||||||
"type": "boolean"
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"prefetch": {
|
"prefetch": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
|
37
store/app.py
|
@ -31,6 +31,8 @@ from utils import (
|
||||||
get_wishlist,
|
get_wishlist,
|
||||||
get_stars,
|
get_stars,
|
||||||
get_app_md_and_screenshots,
|
get_app_md_and_screenshots,
|
||||||
|
save_wishlist_submit_for_ratelimit,
|
||||||
|
check_wishlist_submit_ratelimit,
|
||||||
)
|
)
|
||||||
|
|
||||||
app = Flask(__name__, static_url_path="/assets", static_folder="assets")
|
app = Flask(__name__, static_url_path="/assets", static_folder="assets")
|
||||||
|
@ -147,7 +149,7 @@ def star_app(app_id, action):
|
||||||
if app_id not in get_catalog()["apps"] and app_id not in get_wishlist():
|
if app_id not in get_catalog()["apps"] and app_id not in get_wishlist():
|
||||||
return _("App %(app_id) not found", app_id=app_id), 404
|
return _("App %(app_id) not found", app_id=app_id), 404
|
||||||
if not session.get("user", {}):
|
if not session.get("user", {}):
|
||||||
return _("You must be logged in to be able to star an app"), 401
|
return _("You must be logged in to be able to star an app") + "<br/><br/>" + _("Note that, due to various abuses, we restricted login on the app store to 'trust level 1' users.<br/><br/>'Trust level 1' is obtained after interacting a minimum with the forum, and more specifically: entering at least 5 topics, reading at least 30 posts, and spending at least 10 minutes reading posts."), 401
|
||||||
|
|
||||||
app_star_folder = os.path.join(".stars", app_id)
|
app_star_folder = os.path.join(".stars", app_id)
|
||||||
app_star_for_this_user = os.path.join(
|
app_star_for_this_user = os.path.join(
|
||||||
|
@ -190,7 +192,7 @@ def add_to_wishlist():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
user = session.get("user", {})
|
user = session.get("user", {})
|
||||||
if not user:
|
if not user:
|
||||||
errormsg = _("You must be logged in to submit an app to the wishlist")
|
errormsg = _("You must be logged in to submit an app to the wishlist") + "<br/><br/>" + _("Note that, due to various abuses, we restricted login on the app store to 'trust level 1' users.<br/><br/>'Trust level 1' is obtained after interacting a minimum with the forum, and more specifically: entering at least 5 topics, reading at least 30 posts, and spending at least 10 minutes reading posts.")
|
||||||
return render_template(
|
return render_template(
|
||||||
"wishlist_add.html",
|
"wishlist_add.html",
|
||||||
locale=get_locale(),
|
locale=get_locale(),
|
||||||
|
@ -199,7 +201,6 @@ def add_to_wishlist():
|
||||||
successmsg=None,
|
successmsg=None,
|
||||||
errormsg=errormsg,
|
errormsg=errormsg,
|
||||||
)
|
)
|
||||||
|
|
||||||
csrf_token = request.form["csrf_token"]
|
csrf_token = request.form["csrf_token"]
|
||||||
|
|
||||||
if csrf_token != session.get("csrf_token"):
|
if csrf_token != session.get("csrf_token"):
|
||||||
|
@ -217,8 +218,15 @@ def add_to_wishlist():
|
||||||
description = request.form["description"].strip().replace("\n", "")
|
description = request.form["description"].strip().replace("\n", "")
|
||||||
upstream = request.form["upstream"].strip().replace("\n", "")
|
upstream = request.form["upstream"].strip().replace("\n", "")
|
||||||
website = request.form["website"].strip().replace("\n", "")
|
website = request.form["website"].strip().replace("\n", "")
|
||||||
|
license = request.form["license"].strip().replace("\n", "")
|
||||||
|
|
||||||
|
boring_keywords_to_check_for_people_not_reading_the_instructions = ["free", "open source", "open-source", "self-hosted", "simple", "lightweight", "light-weight", "best", "most", "fast", "flexible", "puissante", "powerful", "secure"]
|
||||||
|
|
||||||
checks = [
|
checks = [
|
||||||
|
(
|
||||||
|
check_wishlist_submit_ratelimit(session['user']['username']) is True,
|
||||||
|
_("Proposing wishlist additions is limited to once every 15 days per user.")
|
||||||
|
),
|
||||||
(len(name) >= 3, _("App name should be at least 3 characters")),
|
(len(name) >= 3, _("App name should be at least 3 characters")),
|
||||||
(len(name) <= 30, _("App name should be less than 30 characters")),
|
(len(name) <= 30, _("App name should be less than 30 characters")),
|
||||||
(
|
(
|
||||||
|
@ -237,11 +245,27 @@ def add_to_wishlist():
|
||||||
len(upstream) <= 150,
|
len(upstream) <= 150,
|
||||||
_("Upstream code repo URL should be less than 150 characters"),
|
_("Upstream code repo URL should be less than 150 characters"),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
len(license) >= 10,
|
||||||
|
_("License URL should be at least 10 characters"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
len(license) <= 250,
|
||||||
|
_("License URL should be less than 250 characters"),
|
||||||
|
),
|
||||||
(len(website) <= 150, _("Website URL should be less than 150 characters")),
|
(len(website) <= 150, _("Website URL should be less than 150 characters")),
|
||||||
(
|
(
|
||||||
re.match(r"^[\w\.\-\(\)\ ]+$", name),
|
re.match(r"^[\w\.\-\(\)\ ]+$", name),
|
||||||
_("App name contains special characters"),
|
_("App name contains special characters"),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
all(keyword not in description.lower() for keyword in boring_keywords_to_check_for_people_not_reading_the_instructions),
|
||||||
|
_("Please focus on what the app does, without using marketing, fuzzy terms, or repeating that the app is 'free' and 'self-hostable'.")
|
||||||
|
),
|
||||||
|
(
|
||||||
|
description.lower().split()[0] != name and (len(description.split()) == 1 or description.lower().split()[1] not in ["is", "est"]),
|
||||||
|
_("No need to repeat '{app} is'. Focus on what the app does.")
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
for check, errormsg in checks:
|
for check, errormsg in checks:
|
||||||
|
@ -328,6 +352,7 @@ Proposed by **{session['user']['username']}**
|
||||||
|
|
||||||
Website: {website}
|
Website: {website}
|
||||||
Upstream repo: {upstream}
|
Upstream repo: {upstream}
|
||||||
|
License: {license}
|
||||||
Description: {description}
|
Description: {description}
|
||||||
|
|
||||||
- [ ] Confirm app is self-hostable and generally makes sense to possibly integrate in YunoHost
|
- [ ] Confirm app is self-hostable and generally makes sense to possibly integrate in YunoHost
|
||||||
|
@ -349,6 +374,9 @@ Description: {description}
|
||||||
"Your proposed app has succesfully been submitted. It must now be validated by the YunoHost team. You can track progress here: <a href='%(url)s'>%(url)s</a>",
|
"Your proposed app has succesfully been submitted. It must now be validated by the YunoHost team. You can track progress here: <a href='%(url)s'>%(url)s</a>",
|
||||||
url=url,
|
url=url,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
save_wishlist_submit_for_ratelimit(session['user']['username'])
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"wishlist_add.html",
|
"wishlist_add.html",
|
||||||
locale=get_locale(),
|
locale=get_locale(),
|
||||||
|
@ -414,6 +442,9 @@ def sso_login_callback():
|
||||||
|
|
||||||
uri_to_redirect_to_after_login = session.get("uri_to_redirect_to_after_login")
|
uri_to_redirect_to_after_login = session.get("uri_to_redirect_to_after_login")
|
||||||
|
|
||||||
|
if "trust_level_1" not in user_data['groups'][0].split(','):
|
||||||
|
return _("Unfortunately, login was denied.") + "<br/><br/>" + _("Note that, due to various abuses, we restricted login on the app store to 'trust level 1' users.<br/><br/>'Trust level 1' is obtained after interacting a minimum with the forum, and more specifically: entering at least 5 topics, reading at least 30 posts, and spending at least 10 minutes reading posts."), 403
|
||||||
|
|
||||||
session.clear()
|
session.clear()
|
||||||
session["user"] = {
|
session["user"] = {
|
||||||
"id": user_data["external_id"][0],
|
"id": user_data["external_id"][0],
|
||||||
|
|
|
@ -27,20 +27,24 @@
|
||||||
<p class="mt-2 text-sm text-orange-700 font-bold">
|
<p class="mt-2 text-sm text-orange-700 font-bold">
|
||||||
<i class="fa fa-exclamation-triangle fa-fw" aria-hidden="true"></i>
|
<i class="fa fa-exclamation-triangle fa-fw" aria-hidden="true"></i>
|
||||||
{{ _("You must first login to be allowed to submit an app to the wishlist") }}
|
{{ _("You must first login to be allowed to submit an app to the wishlist") }}
|
||||||
|
<br/><br/>
|
||||||
|
</p>
|
||||||
|
<p class="mt-2 text-sm text-orange-700">
|
||||||
|
{{ _("Note that, due to various abuses, we restricted login on the app store to 'trust level 1' users.<br/><br/>'Trust level 1' is obtained after interacting a minimum with the forum, and more specifically: entering at least 5 topics, reading at least 30 posts, and spending at least 10 minutes reading posts.") }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div role="alert" class="rounded-md border-s-4 border-orange-500 bg-orange-50 p-4 mb-5">
|
||||||
|
<p class="mt-2 text-sm text-orange-700 font-bold">
|
||||||
|
<i class="fa fa-exclamation-triangle fa-fw" aria-hidden="true"></i>
|
||||||
|
{{ _("Due to abuses, only one proposal every 15 days per user is allowed.") }}
|
||||||
|
</p>
|
||||||
|
<p class="mt-2 text-sm text-orange-700">
|
||||||
|
{{ _("Reviewing those proposals is tiring for volunteers, please don't yolo-send every random nerdy stuff you find on the Internet.") }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div role="alert" class="rounded-md border-s-4 border-sky-500 bg-sky-50 p-4">
|
|
||||||
<p class="mt-2 text-sm text-sky-700 font-bold">
|
|
||||||
<i class="fa fa-info-circle fa-fw" aria-hidden="true"></i>
|
|
||||||
{{ _("Please check the license of the app your are proposing") }}
|
|
||||||
</p>
|
|
||||||
<p class="mt-2 text-sm text-sky-700">
|
|
||||||
{{ _("The YunoHost project will only package free/open-source software (with possible case-by-case exceptions for apps which are not-totally-free)") }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if errormsg %}
|
{% if errormsg %}
|
||||||
<div role="alert" class="rounded-md border-s-4 border-red-500 bg-red-50 p-4 my-5">
|
<div role="alert" class="rounded-md border-s-4 border-red-500 bg-red-50 p-4 my-5">
|
||||||
<p class="mt-2 text-sm text-red-700 font-bold">
|
<p class="mt-2 text-sm text-red-700 font-bold">
|
||||||
|
@ -64,6 +68,10 @@
|
||||||
<label for="upstream" class="mt-5 block font-bold text-gray-700">{{ _("Project code repository") }}</label>
|
<label for="upstream" class="mt-5 block font-bold text-gray-700">{{ _("Project code repository") }}</label>
|
||||||
<input name="upstream" type="url" class="w-full mt-1 rounded-md border-gray-200 text-gray-700 shadow-sm" maxlength="150" required >
|
<input name="upstream" type="url" class="w-full mt-1 rounded-md border-gray-200 text-gray-700 shadow-sm" maxlength="150" required >
|
||||||
|
|
||||||
|
<label for="license" class="mt-5 block font-bold text-gray-700">{{ _("Link to the project's LICENSE") }}</label>
|
||||||
|
<input name="license" type="url" class="w-full mt-1 rounded-md border-gray-200 text-gray-700 shadow-sm" required maxlength="250"></input>
|
||||||
|
<span class="text-xs text-gray-600 font-bold">{{ _("The YunoHost project will only package free/open-source software (with possible case-by-case exceptions for apps which are not-totally-free)") }}</span>
|
||||||
|
|
||||||
<label for="website" class="mt-5 block font-bold text-gray-700">{{ _("Project website") }}</label>
|
<label for="website" class="mt-5 block font-bold text-gray-700">{{ _("Project website") }}</label>
|
||||||
<input name="website" type="url" class="w-full mt-1 rounded-md border-gray-200 text-gray-700 shadow-sm" maxlength="150" >
|
<input name="website" type="url" class="w-full mt-1 rounded-md border-gray-200 text-gray-700 shadow-sm" maxlength="150" >
|
||||||
<span class="text-xs text-gray-600">{{ _("Please *do not* just copy-paste the code repository URL. If the project has no proper website, then leave the field empty.") }}</span>
|
<span class="text-xs text-gray-600">{{ _("Please *do not* just copy-paste the code repository URL. If the project has no proper website, then leave the field empty.") }}</span>
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2023-09-19 17:04+0200\n"
|
"POT-Creation-Date: 2023-11-19 19:39+0100\n"
|
||||||
"PO-Revision-Date: 2023-09-05 19:50+0200\n"
|
"PO-Revision-Date: 2023-09-05 19:50+0200\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
|
@ -18,59 +18,73 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.12.1\n"
|
"Generated-By: Babel 2.12.1\n"
|
||||||
|
|
||||||
#: app.py:140
|
#: app.py:148
|
||||||
msgid "App %(app_id) not found"
|
msgid "App %(app_id) not found"
|
||||||
msgstr "L'app %(app_id) n'a pas été trouvée"
|
msgstr "L'app %(app_id) n'a pas été trouvée"
|
||||||
|
|
||||||
#: app.py:142
|
#: app.py:150
|
||||||
msgid "You must be logged in to be able to star an app"
|
msgid "You must be logged in to be able to star an app"
|
||||||
msgstr "Vous devez être connecté·e pour mettre une app en favoris"
|
msgstr "Vous devez être connecté·e pour mettre une app en favoris"
|
||||||
|
|
||||||
#: app.py:185
|
#: app.py:150 app.py:193 app.py:418 templates/wishlist_add.html:31
|
||||||
|
msgid ""
|
||||||
|
"Note that, due to various abuses, we restricted login on the app store to"
|
||||||
|
" 'trust level 1' users.<br/><br/>'Trust level 1' is obtained after "
|
||||||
|
"interacting a minimum with the forum, and more specifically: entering at "
|
||||||
|
"least 5 topics, reading at least 30 posts, and spending at least 10 "
|
||||||
|
"minutes reading posts."
|
||||||
|
msgstr ""
|
||||||
|
"Notez que, suite à divers abus, la connexion nécessite maintenant d'être"
|
||||||
|
" 'trust level 1' sur le forum.<br/><br/>Le 'trust level 1' est obtenu après"
|
||||||
|
" avoir intéragit un minimum avec le forum, et plus précisémment: ouvrir au"
|
||||||
|
" moins 5 fils de discussion, lire au moins 30 messages, et passer au moins"
|
||||||
|
" 10 minutes à lire des messages."
|
||||||
|
|
||||||
|
#: app.py:193
|
||||||
msgid "You must be logged in to submit an app to the wishlist"
|
msgid "You must be logged in to submit an app to the wishlist"
|
||||||
msgstr "Vous devez être connecté·e pour proposer une app pour la liste de souhaits"
|
msgstr "Vous devez être connecté·e pour proposer une app pour la liste de souhaits"
|
||||||
|
|
||||||
#: app.py:200
|
#: app.py:206
|
||||||
msgid "Invalid CSRF token, please refresh the form and try again"
|
msgid "Invalid CSRF token, please refresh the form and try again"
|
||||||
msgstr "Jeton CSRF invalide, prière de rafraîchir la page et retenter"
|
msgstr "Jeton CSRF invalide, prière de rafraîchir la page et retenter"
|
||||||
|
|
||||||
#: app.py:216
|
#: app.py:222
|
||||||
msgid "App name should be at least 3 characters"
|
msgid "App name should be at least 3 characters"
|
||||||
msgstr "Le nom d'app devrait contenir au moins 3 caractères"
|
msgstr "Le nom d'app devrait contenir au moins 3 caractères"
|
||||||
|
|
||||||
#: app.py:217
|
#: app.py:223
|
||||||
msgid "App name should be less than 30 characters"
|
msgid "App name should be less than 30 characters"
|
||||||
msgstr "Le nom d'app devrait contenir moins de 30 caractères"
|
msgstr "Le nom d'app devrait contenir moins de 30 caractères"
|
||||||
|
|
||||||
#: app.py:220
|
#: app.py:226
|
||||||
msgid "App description should be at least 5 characters"
|
msgid "App description should be at least 5 characters"
|
||||||
msgstr "La description de l'app devrait contenir au moins 5 caractères"
|
msgstr "La description de l'app devrait contenir au moins 5 caractères"
|
||||||
|
|
||||||
#: app.py:224
|
#: app.py:230
|
||||||
msgid "App description should be less than 100 characters"
|
msgid "App description should be less than 100 characters"
|
||||||
msgstr "La description de l'app devrait contenir moins de 100 caractères"
|
msgstr "La description de l'app devrait contenir moins de 100 caractères"
|
||||||
|
|
||||||
#: app.py:228
|
#: app.py:234
|
||||||
msgid "Upstream code repo URL should be at least 10 characters"
|
msgid "Upstream code repo URL should be at least 10 characters"
|
||||||
msgstr "L'URL du dépôt de code devrait contenir au moins 10 caractères"
|
msgstr "L'URL du dépôt de code devrait contenir au moins 10 caractères"
|
||||||
|
|
||||||
#: app.py:232
|
#: app.py:238
|
||||||
msgid "Upstream code repo URL should be less than 150 characters"
|
msgid "Upstream code repo URL should be less than 150 characters"
|
||||||
msgstr "L'URL du dépôt de code devrait contenir moins de 150 caractères"
|
msgstr "L'URL du dépôt de code devrait contenir moins de 150 caractères"
|
||||||
|
|
||||||
#: app.py:234
|
#: app.py:240
|
||||||
msgid "Website URL should be less than 150 characters"
|
msgid "Website URL should be less than 150 characters"
|
||||||
msgstr "L'URL du site web devrait contenir moins de 150 caractères"
|
msgstr "L'URL du site web devrait contenir moins de 150 caractères"
|
||||||
|
|
||||||
#: app.py:237
|
#: app.py:243
|
||||||
msgid "App name contains special characters"
|
msgid "App name contains special characters"
|
||||||
msgstr "Le nom de l'app contiens des caractères spéciaux"
|
msgstr "Le nom de l'app contiens des caractères spéciaux"
|
||||||
|
|
||||||
#: app.py:270
|
#: app.py:276
|
||||||
msgid "An entry with the name %(slug) already exists in the wishlist"
|
msgid "An entry with the name %(slug) already exists in the wishlist"
|
||||||
msgstr "Une entrée nommée $(slug) existe déjà dans la liste de souhaits"
|
msgstr "Une entrée nommée $(slug) existe déjà dans la liste de souhaits"
|
||||||
|
|
||||||
#: app.py:295
|
#: app.py:299
|
||||||
msgid ""
|
msgid ""
|
||||||
"Failed to create the pull request to add the app to the wishlist ... "
|
"Failed to create the pull request to add the app to the wishlist ... "
|
||||||
"please report the issue to the yunohost team"
|
"please report the issue to the yunohost team"
|
||||||
|
@ -78,15 +92,19 @@ msgstr ""
|
||||||
"Échec de la création de la demande d'intégration de l'app dans la liste "
|
"Échec de la création de la demande d'intégration de l'app dans la liste "
|
||||||
"de souhaits ... merci de rapport le problème à l'équipe YunoHost"
|
"de souhaits ... merci de rapport le problème à l'équipe YunoHost"
|
||||||
|
|
||||||
#: app.py:340
|
#: app.py:348
|
||||||
#, python-format
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your proposed app has succesfully been submitted. It must now be "
|
"Your proposed app has succesfully been submitted. It must now be "
|
||||||
"validated by the YunoHost team. You can track progress here: %(url)s"
|
"validated by the YunoHost team. You can track progress here: <a "
|
||||||
|
"href='%(url)s'>%(url)s</a>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Un demande d'intégration à la liste de souhaits a bien été créée pour "
|
"Un demande d'intégration à la liste de souhaits a bien été créée pour "
|
||||||
"cette app. Elle doit maintenant être validée par l'équipe YunoHost. Vous "
|
"cette app. Elle doit maintenant être validée par l'équipe YunoHost. Vous "
|
||||||
"pouvez suivre cette demande ici: %(url)s"
|
"pouvez suivre cette demande ici: <a href='%(url)s'>%(url)s</a>"
|
||||||
|
|
||||||
|
#: app.py:418
|
||||||
|
msgid "Unfortunately, login was denied."
|
||||||
|
msgstr "Malheureusement, la connexion a été refusée."
|
||||||
|
|
||||||
#: templates/app.html:10 templates/catalog.html:23
|
#: templates/app.html:10 templates/catalog.html:23
|
||||||
#, python-format
|
#, python-format
|
||||||
|
@ -116,7 +134,9 @@ msgstr ""
|
||||||
msgid ""
|
msgid ""
|
||||||
"This app has been good quality according to our automatic tests over at "
|
"This app has been good quality according to our automatic tests over at "
|
||||||
"least one year."
|
"least one year."
|
||||||
msgstr "Cette app est de bonne qualité d'après nos tests automatisés depuis au moins un an."
|
msgstr ""
|
||||||
|
"Cette app est de bonne qualité d'après nos tests automatisés depuis au "
|
||||||
|
"moins un an."
|
||||||
|
|
||||||
#: templates/app.html:81
|
#: templates/app.html:81
|
||||||
msgid "Try the demo"
|
msgid "Try the demo"
|
||||||
|
@ -204,34 +224,45 @@ msgstr "Dépôt de code du paquet YunoHost"
|
||||||
msgid "YunoHost app store"
|
msgid "YunoHost app store"
|
||||||
msgstr "Store d'apps de YunoHost"
|
msgstr "Store d'apps de YunoHost"
|
||||||
|
|
||||||
#: templates/base.html:56 templates/base.html:149 templates/index.html:3
|
#: templates/base.html:18 templates/base.html:113 templates/index.html:3
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "Accueil"
|
msgstr "Accueil"
|
||||||
|
|
||||||
#: templates/base.html:65 templates/base.html:158
|
#: templates/base.html:27 templates/base.html:122
|
||||||
msgid "Catalog"
|
msgid "Catalog"
|
||||||
msgstr "Catalogue"
|
msgstr "Catalogue"
|
||||||
|
|
||||||
#: templates/base.html:71 templates/base.html:167
|
#: templates/base.html:33 templates/base.html:131
|
||||||
msgid "Wishlist"
|
msgid "Wishlist"
|
||||||
msgstr "Liste de souhaits"
|
msgstr "Liste de souhaits"
|
||||||
|
|
||||||
#: templates/base.html:84 templates/base.html:177
|
#: templates/base.html:46 templates/base.html:141
|
||||||
msgid "YunoHost documentation"
|
msgid "YunoHost documentation"
|
||||||
msgstr "Documentation YunoHost"
|
msgstr "Documentation YunoHost"
|
||||||
|
|
||||||
#: templates/base.html:92 templates/base.html:187
|
#: templates/base.html:54 templates/base.html:151
|
||||||
msgid "Login using YunoHost's forum"
|
msgid "Login using YunoHost's forum"
|
||||||
msgstr "Se connecter via le forum YunoHost"
|
msgstr "Se connecter via le forum YunoHost"
|
||||||
|
|
||||||
#: templates/base.html:122 templates/base.html:213
|
#: templates/base.html:86 templates/base.html:179
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Se déconnecter"
|
msgstr "Se déconnecter"
|
||||||
|
|
||||||
#: templates/base.html:135
|
#: templates/base.html:99
|
||||||
msgid "Toggle menu"
|
msgid "Toggle menu"
|
||||||
msgstr "Activer le menu"
|
msgstr "Activer le menu"
|
||||||
|
|
||||||
|
#: templates/base.html:197
|
||||||
|
msgid ""
|
||||||
|
"Made with <i class='text-red-500 fa fa-heart-o' aria-label='love'></i> "
|
||||||
|
"using <a class='text-blue-800' "
|
||||||
|
"href='https://flask.palletsprojects.com'>Flask</a> and <a class='text-"
|
||||||
|
"blue-800' href='https://tailwindcss.com/'>TailwindCSS</a> - <a class"
|
||||||
|
"='text-blue-800' "
|
||||||
|
"href='https://github.com/YunoHost/apps/tree/master/store'><i class='fa "
|
||||||
|
"fa-code fa-fw' aria-hidden='true'></i> Source</a>"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: templates/catalog.html:75 templates/catalog.html:80
|
#: templates/catalog.html:75 templates/catalog.html:80
|
||||||
msgid "Application Catalog"
|
msgid "Application Catalog"
|
||||||
msgstr "Catalogue d'applications"
|
msgstr "Catalogue d'applications"
|
||||||
|
@ -253,17 +284,17 @@ msgid "Sort by"
|
||||||
msgstr "Trier par"
|
msgstr "Trier par"
|
||||||
|
|
||||||
#: templates/catalog.html:123 templates/wishlist.html:45
|
#: templates/catalog.html:123 templates/wishlist.html:45
|
||||||
msgid "Alphabetical"
|
#: templates/wishlist.html:78
|
||||||
msgstr "Alphabétique"
|
msgid "Popularity"
|
||||||
|
msgstr "Popularité"
|
||||||
|
|
||||||
#: templates/catalog.html:124
|
#: templates/catalog.html:124
|
||||||
msgid "Newest"
|
msgid "Newest"
|
||||||
msgstr "Nouveauté"
|
msgstr "Nouveauté"
|
||||||
|
|
||||||
#: templates/catalog.html:125 templates/wishlist.html:46
|
#: templates/catalog.html:125 templates/wishlist.html:46
|
||||||
#: templates/wishlist.html:78
|
msgid "Alphabetical"
|
||||||
msgid "Popularity"
|
msgstr "Alphabétique"
|
||||||
msgstr "Popularité"
|
|
||||||
|
|
||||||
#: templates/catalog.html:128 templates/wishlist.html:49
|
#: templates/catalog.html:128 templates/wishlist.html:49
|
||||||
msgid "Requires to be logged-in"
|
msgid "Requires to be logged-in"
|
||||||
|
@ -274,7 +305,7 @@ msgstr "Nécessite d'être connecté·e"
|
||||||
msgid "Show only apps you starred"
|
msgid "Show only apps you starred"
|
||||||
msgstr "Montrer uniquement mes favoris"
|
msgstr "Montrer uniquement mes favoris"
|
||||||
|
|
||||||
#: templates/catalog.html:155 templates/wishlist.html:152
|
#: templates/catalog.html:155 templates/wishlist.html:154
|
||||||
msgid "No results found."
|
msgid "No results found."
|
||||||
msgstr "Aucun résultat trouvé."
|
msgstr "Aucun résultat trouvé."
|
||||||
|
|
||||||
|
@ -326,7 +357,7 @@ msgstr ""
|
||||||
msgid "Suggest an app"
|
msgid "Suggest an app"
|
||||||
msgstr "Suggérer une app"
|
msgstr "Suggérer une app"
|
||||||
|
|
||||||
#: templates/wishlist.html:71 templates/wishlist_add.html:57
|
#: templates/wishlist.html:71 templates/wishlist_add.html:59
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
|
@ -338,11 +369,11 @@ msgstr "Description"
|
||||||
msgid "Official website"
|
msgid "Official website"
|
||||||
msgstr "Site officiel"
|
msgstr "Site officiel"
|
||||||
|
|
||||||
#: templates/wishlist.html:114 templates/wishlist.html:115
|
#: templates/wishlist.html:115 templates/wishlist.html:116
|
||||||
msgid "Code repository"
|
msgid "Code repository"
|
||||||
msgstr "Dépôt de code officiel"
|
msgstr "Dépôt de code officiel"
|
||||||
|
|
||||||
#: templates/wishlist.html:127 templates/wishlist.html:128
|
#: templates/wishlist.html:129 templates/wishlist.html:130
|
||||||
msgid "Star this app"
|
msgid "Star this app"
|
||||||
msgstr "Étoiler cette app"
|
msgstr "Étoiler cette app"
|
||||||
|
|
||||||
|
@ -354,11 +385,11 @@ msgstr "Suggérer une application à ajouter dans le catalogue de YunoHost"
|
||||||
msgid "You must first login to be allowed to submit an app to the wishlist"
|
msgid "You must first login to be allowed to submit an app to the wishlist"
|
||||||
msgstr "Vous devez être connecté·e pour proposer une app pour la liste de souhaits"
|
msgstr "Vous devez être connecté·e pour proposer une app pour la liste de souhaits"
|
||||||
|
|
||||||
#: templates/wishlist_add.html:37
|
#: templates/wishlist_add.html:39
|
||||||
msgid "Please check the license of the app your are proposing"
|
msgid "Please check the license of the app your are proposing"
|
||||||
msgstr "Merci de vérifier la licence de l'app que vous proposez"
|
msgstr "Merci de vérifier la licence de l'app que vous proposez"
|
||||||
|
|
||||||
#: templates/wishlist_add.html:40
|
#: templates/wishlist_add.html:42
|
||||||
msgid ""
|
msgid ""
|
||||||
"The YunoHost project will only package free/open-source software (with "
|
"The YunoHost project will only package free/open-source software (with "
|
||||||
"possible case-by-case exceptions for apps which are not-totally-free)"
|
"possible case-by-case exceptions for apps which are not-totally-free)"
|
||||||
|
@ -367,15 +398,15 @@ msgstr ""
|
||||||
"(avec quelques possibles exceptions au cas-par-cas pour des apps qui ne "
|
"(avec quelques possibles exceptions au cas-par-cas pour des apps qui ne "
|
||||||
"sont pas entièrement libres)"
|
"sont pas entièrement libres)"
|
||||||
|
|
||||||
#: templates/wishlist_add.html:60
|
#: templates/wishlist_add.html:62
|
||||||
msgid "App's description"
|
msgid "App's description"
|
||||||
msgstr "Description de l'app"
|
msgstr "Description de l'app"
|
||||||
|
|
||||||
#: templates/wishlist_add.html:62
|
#: templates/wishlist_add.html:64
|
||||||
msgid "Please be concise and focus on what the app does."
|
msgid "Please be concise and focus on what the app does."
|
||||||
msgstr "Prière de rester concis et de se concentrer sur ce que l'app fait."
|
msgstr "Prière de rester concis et de se concentrer sur ce que l'app fait."
|
||||||
|
|
||||||
#: templates/wishlist_add.html:62
|
#: templates/wishlist_add.html:64
|
||||||
msgid ""
|
msgid ""
|
||||||
"No need to repeat '[App] is ...'. No need to state that it is free/open-"
|
"No need to repeat '[App] is ...'. No need to state that it is free/open-"
|
||||||
"source or self-hosted (otherwise it wouldn't be packaged for YunoHost). "
|
"source or self-hosted (otherwise it wouldn't be packaged for YunoHost). "
|
||||||
|
@ -387,15 +418,15 @@ msgstr ""
|
||||||
"Évitez les formulations marketing type 'le meilleur', ou les propriétés "
|
"Évitez les formulations marketing type 'le meilleur', ou les propriétés "
|
||||||
"vagues telles que 'facile', 'simple', 'léger'."
|
"vagues telles que 'facile', 'simple', 'léger'."
|
||||||
|
|
||||||
#: templates/wishlist_add.html:64
|
#: templates/wishlist_add.html:66
|
||||||
msgid "Project code repository"
|
msgid "Project code repository"
|
||||||
msgstr "Dépôt de code officiel"
|
msgstr "Dépôt de code officiel"
|
||||||
|
|
||||||
#: templates/wishlist_add.html:67
|
#: templates/wishlist_add.html:69
|
||||||
msgid "Project website"
|
msgid "Project website"
|
||||||
msgstr "Site officiel"
|
msgstr "Site officiel"
|
||||||
|
|
||||||
#: templates/wishlist_add.html:69
|
#: templates/wishlist_add.html:71
|
||||||
msgid ""
|
msgid ""
|
||||||
"Please *do not* just copy-paste the code repository URL. If the project "
|
"Please *do not* just copy-paste the code repository URL. If the project "
|
||||||
"has no proper website, then leave the field empty."
|
"has no proper website, then leave the field empty."
|
||||||
|
@ -403,7 +434,7 @@ msgstr ""
|
||||||
"Prière de *ne pas* juste copier-coller l'URL du dépôt de code. Si le "
|
"Prière de *ne pas* juste copier-coller l'URL du dépôt de code. Si le "
|
||||||
"projet n'a pas de vrai site web, laissez le champ vide."
|
"projet n'a pas de vrai site web, laissez le champ vide."
|
||||||
|
|
||||||
#: templates/wishlist_add.html:76
|
#: templates/wishlist_add.html:78
|
||||||
msgid "Submit"
|
msgid "Submit"
|
||||||
msgstr "Envoyer"
|
msgstr "Envoyer"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import time
|
||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
@ -6,7 +7,7 @@ import subprocess
|
||||||
import pycmarkgfm
|
import pycmarkgfm
|
||||||
from emoji import emojize
|
from emoji import emojize
|
||||||
from flask import request
|
from flask import request
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
AVAILABLE_LANGUAGES = ["en"] + os.listdir("translations")
|
AVAILABLE_LANGUAGES = ["en"] + os.listdir("translations")
|
||||||
|
|
||||||
|
@ -92,6 +93,26 @@ def get_stars():
|
||||||
get_stars.cache_checksum = None
|
get_stars.cache_checksum = None
|
||||||
get_stars()
|
get_stars()
|
||||||
|
|
||||||
|
def check_wishlist_submit_ratelimit(user):
|
||||||
|
|
||||||
|
dir_ = os.path.join(".wishlist_ratelimit")
|
||||||
|
if not os.path.exists(dir_):
|
||||||
|
os.mkdir(dir_)
|
||||||
|
|
||||||
|
f = os.path.join(dir_, md5(user.encode()).hexdigest())
|
||||||
|
|
||||||
|
return not os.path.exists(f) or (time.time() - os.path.getmtime(f)) > (15 * 24 * 3600) # 15 days
|
||||||
|
|
||||||
|
def save_wishlist_submit_for_ratelimit(user):
|
||||||
|
|
||||||
|
dir_ = os.path.join(".wishlist_ratelimit")
|
||||||
|
if not os.path.exists(dir_):
|
||||||
|
os.mkdir(dir_)
|
||||||
|
|
||||||
|
f = os.path.join(dir_, md5(user.encode()).hexdigest())
|
||||||
|
|
||||||
|
open(f, "w").write("")
|
||||||
|
|
||||||
|
|
||||||
def human_to_binary(size: str) -> int:
|
def human_to_binary(size: str) -> int:
|
||||||
symbols = ("K", "M", "G", "T", "P", "E", "Z", "Y")
|
symbols = ("K", "M", "G", "T", "P", "E", "Z", "Y")
|
||||||
|
|
|
@ -47,7 +47,6 @@ else:
|
||||||
|
|
||||||
|
|
||||||
def apps_to_run_auto_update_for():
|
def apps_to_run_auto_update_for():
|
||||||
|
|
||||||
catalog = toml.load(open(os.path.dirname(__file__) + "/../../apps.toml"))
|
catalog = toml.load(open(os.path.dirname(__file__) + "/../../apps.toml"))
|
||||||
|
|
||||||
apps_flagged_as_working_and_on_yunohost_apps_org = [
|
apps_flagged_as_working_and_on_yunohost_apps_org = [
|
||||||
|
@ -105,7 +104,6 @@ def filter_and_get_latest_tag(tags, app_id):
|
||||||
|
|
||||||
|
|
||||||
def tag_to_int_tuple(tag):
|
def tag_to_int_tuple(tag):
|
||||||
|
|
||||||
tag = tag.strip("v").strip(".")
|
tag = tag.strip("v").strip(".")
|
||||||
int_tuple = tag.split(".")
|
int_tuple = tag.split(".")
|
||||||
assert all(i.isdigit() for i in int_tuple), f"Cant convert {tag} to int tuple :/"
|
assert all(i.isdigit() for i in int_tuple), f"Cant convert {tag} to int tuple :/"
|
||||||
|
@ -127,7 +125,6 @@ def sha256_of_remote_file(url):
|
||||||
|
|
||||||
class AppAutoUpdater:
|
class AppAutoUpdater:
|
||||||
def __init__(self, app_id, app_id_is_local_app_dir=False):
|
def __init__(self, app_id, app_id_is_local_app_dir=False):
|
||||||
|
|
||||||
if app_id_is_local_app_dir:
|
if app_id_is_local_app_dir:
|
||||||
if not os.path.exists(app_id + "/manifest.toml"):
|
if not os.path.exists(app_id + "/manifest.toml"):
|
||||||
raise Exception("manifest.toml doesnt exists?")
|
raise Exception("manifest.toml doesnt exists?")
|
||||||
|
@ -158,11 +155,9 @@ class AppAutoUpdater:
|
||||||
self.main_upstream = manifest.get("upstream", {}).get("code")
|
self.main_upstream = manifest.get("upstream", {}).get("code")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
||||||
todos = {}
|
todos = {}
|
||||||
|
|
||||||
for source, infos in self.sources.items():
|
for source, infos in self.sources.items():
|
||||||
|
|
||||||
if "autoupdate" not in infos:
|
if "autoupdate" not in infos:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -176,9 +171,16 @@ class AppAutoUpdater:
|
||||||
|
|
||||||
print(f"\n Checking {source} ...")
|
print(f"\n Checking {source} ...")
|
||||||
|
|
||||||
new_version, new_asset_urls = self.get_latest_version_and_asset(
|
if strategy == "latest_github_release":
|
||||||
strategy, asset, infos, source
|
(
|
||||||
)
|
new_version,
|
||||||
|
new_asset_urls,
|
||||||
|
changelog_url,
|
||||||
|
) = self.get_latest_version_and_asset(strategy, asset, infos, source)
|
||||||
|
else:
|
||||||
|
(new_version, new_asset_urls) = self.get_latest_version_and_asset(
|
||||||
|
strategy, asset, infos, source
|
||||||
|
)
|
||||||
|
|
||||||
if source == "main":
|
if source == "main":
|
||||||
print(f"Current version in manifest: {self.current_version}")
|
print(f"Current version in manifest: {self.current_version}")
|
||||||
|
@ -190,8 +192,12 @@ class AppAutoUpdater:
|
||||||
# Though we wrap this in a try/except pass, because don't want to miserably crash
|
# Though we wrap this in a try/except pass, because don't want to miserably crash
|
||||||
# if the tag can't properly be converted to int tuple ...
|
# if the tag can't properly be converted to int tuple ...
|
||||||
try:
|
try:
|
||||||
if tag_to_int_tuple(self.current_version) > tag_to_int_tuple(new_version):
|
if tag_to_int_tuple(self.current_version) > tag_to_int_tuple(
|
||||||
print("Up to date (current version appears more recent than newest version found)")
|
new_version
|
||||||
|
):
|
||||||
|
print(
|
||||||
|
"Up to date (current version appears more recent than newest version found)"
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
@ -200,9 +206,15 @@ class AppAutoUpdater:
|
||||||
print("Up to date")
|
print("Up to date")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (isinstance(new_asset_urls, dict) and isinstance(infos.get("url"), str)) \
|
if (
|
||||||
or (isinstance(new_asset_urls, str) and not isinstance(infos.get("url"), str)):
|
isinstance(new_asset_urls, dict) and isinstance(infos.get("url"), str)
|
||||||
raise Exception(f"It looks like there's an inconsistency between the old asset list and the new ones ... one is arch-specific, the other is not ... Did you forget to define arch-specific regexes ? ... New asset url is/are : {new_asset_urls}")
|
) or (
|
||||||
|
isinstance(new_asset_urls, str)
|
||||||
|
and not isinstance(infos.get("url"), str)
|
||||||
|
):
|
||||||
|
raise Exception(
|
||||||
|
f"It looks like there's an inconsistency between the old asset list and the new ones ... one is arch-specific, the other is not ... Did you forget to define arch-specific regexes ? ... New asset url is/are : {new_asset_urls}"
|
||||||
|
)
|
||||||
|
|
||||||
if isinstance(new_asset_urls, str) and infos["url"] == new_asset_urls:
|
if isinstance(new_asset_urls, str) and infos["url"] == new_asset_urls:
|
||||||
print(f"URL for asset {source} is up to date")
|
print(f"URL for asset {source} is up to date")
|
||||||
|
@ -226,11 +238,15 @@ class AppAutoUpdater:
|
||||||
return bool(todos)
|
return bool(todos)
|
||||||
|
|
||||||
if "main" in todos:
|
if "main" in todos:
|
||||||
|
if strategy == "latest_github_release":
|
||||||
|
title = f"Upgrade to v{new_version}"
|
||||||
|
message = f"Upgrade to v{new_version}\nChangelog: {changelog_url}"
|
||||||
|
else:
|
||||||
|
title = message = f"Upgrade to v{new_version}"
|
||||||
new_version = todos["main"]["new_version"]
|
new_version = todos["main"]["new_version"]
|
||||||
message = f"Upgrade to v{new_version}"
|
|
||||||
new_branch = f"ci-auto-update-{new_version}"
|
new_branch = f"ci-auto-update-{new_version}"
|
||||||
else:
|
else:
|
||||||
message = "Upgrade sources"
|
title = message = "Upgrade sources"
|
||||||
new_branch = "ci-auto-update-sources"
|
new_branch = "ci-auto-update-sources"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -265,7 +281,7 @@ class AppAutoUpdater:
|
||||||
|
|
||||||
# Open the PR
|
# Open the PR
|
||||||
pr = self.repo.create_pull(
|
pr = self.repo.create_pull(
|
||||||
title=message, body=message, head=new_branch, base=self.base_branch
|
title=title, body=message, head=new_branch, base=self.base_branch
|
||||||
)
|
)
|
||||||
|
|
||||||
print("Created PR " + self.repo.full_name + " updated with PR #" + str(pr.id))
|
print("Created PR " + self.repo.full_name + " updated with PR #" + str(pr.id))
|
||||||
|
@ -273,12 +289,13 @@ class AppAutoUpdater:
|
||||||
return bool(todos)
|
return bool(todos)
|
||||||
|
|
||||||
def get_latest_version_and_asset(self, strategy, asset, infos, source):
|
def get_latest_version_and_asset(self, strategy, asset, infos, source):
|
||||||
|
upstream = (
|
||||||
upstream = infos.get("autoupdate", {}).get("upstream", self.main_upstream).strip("/")
|
infos.get("autoupdate", {}).get("upstream", self.main_upstream).strip("/")
|
||||||
|
)
|
||||||
|
|
||||||
if "github" in strategy:
|
if "github" in strategy:
|
||||||
assert upstream and upstream.startswith(
|
assert (
|
||||||
"https://github.com/"
|
upstream and upstream.startswith("https://github.com/")
|
||||||
), f"When using strategy {strategy}, having a defined upstream code repo on github.com is required"
|
), f"When using strategy {strategy}, having a defined upstream code repo on github.com is required"
|
||||||
api = GithubAPI(upstream, auth=auth)
|
api = GithubAPI(upstream, auth=auth)
|
||||||
elif "gitlab" in strategy:
|
elif "gitlab" in strategy:
|
||||||
|
@ -294,24 +311,24 @@ class AppAutoUpdater:
|
||||||
latest_version_orig, latest_version = filter_and_get_latest_tag(
|
latest_version_orig, latest_version = filter_and_get_latest_tag(
|
||||||
tags, self.app_id
|
tags, self.app_id
|
||||||
)
|
)
|
||||||
|
latest_release = [
|
||||||
|
release
|
||||||
|
for release in releases
|
||||||
|
if release["tag_name"] == latest_version_orig
|
||||||
|
][0]
|
||||||
|
latest_assets = {
|
||||||
|
a["name"]: a["browser_download_url"]
|
||||||
|
for a in latest_release["assets"]
|
||||||
|
if not a["name"].endswith(".md5")
|
||||||
|
}
|
||||||
|
latest_release_html_url = latest_release["html_url"]
|
||||||
if asset == "tarball":
|
if asset == "tarball":
|
||||||
latest_tarball = (
|
latest_tarball = (
|
||||||
api.url_for_ref(latest_version_orig, RefType.tags)
|
api.url_for_ref(latest_version_orig, RefType.tags)
|
||||||
)
|
)
|
||||||
return latest_version, latest_tarball
|
return latest_version, latest_tarball, latest_release_html_url
|
||||||
# FIXME
|
# FIXME
|
||||||
else:
|
else:
|
||||||
latest_release = [
|
|
||||||
release
|
|
||||||
for release in releases
|
|
||||||
if release["tag_name"] == latest_version_orig
|
|
||||||
][0]
|
|
||||||
latest_assets = {
|
|
||||||
a["name"]: a["browser_download_url"]
|
|
||||||
for a in latest_release["assets"]
|
|
||||||
if not a["name"].endswith(".md5")
|
|
||||||
}
|
|
||||||
latest_release_html_url = latest_release["html_url"]
|
|
||||||
if isinstance(asset, str):
|
if isinstance(asset, str):
|
||||||
matching_assets_urls = [
|
matching_assets_urls = [
|
||||||
url
|
url
|
||||||
|
@ -326,7 +343,11 @@ class AppAutoUpdater:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
f"Too many assets matching regex '{asset}' for release {latest_version} : {matching_assets_urls}. Full release details on {latest_release_html_url}"
|
f"Too many assets matching regex '{asset}' for release {latest_version} : {matching_assets_urls}. Full release details on {latest_release_html_url}"
|
||||||
)
|
)
|
||||||
return latest_version, matching_assets_urls[0]
|
return (
|
||||||
|
latest_version,
|
||||||
|
matching_assets_urls[0],
|
||||||
|
latest_release_html_url,
|
||||||
|
)
|
||||||
elif isinstance(asset, dict):
|
elif isinstance(asset, dict):
|
||||||
matching_assets_dicts = {}
|
matching_assets_dicts = {}
|
||||||
for asset_name, asset_regex in asset.items():
|
for asset_name, asset_regex in asset.items():
|
||||||
|
@ -344,7 +365,11 @@ class AppAutoUpdater:
|
||||||
f"Too many assets matching regex '{asset}' for release {latest_version} : {matching_assets_urls}. Full release details on {latest_release_html_url}"
|
f"Too many assets matching regex '{asset}' for release {latest_version} : {matching_assets_urls}. Full release details on {latest_release_html_url}"
|
||||||
)
|
)
|
||||||
matching_assets_dicts[asset_name] = matching_assets_urls[0]
|
matching_assets_dicts[asset_name] = matching_assets_urls[0]
|
||||||
return latest_version.strip("v"), matching_assets_dicts
|
return (
|
||||||
|
latest_version.strip("v"),
|
||||||
|
matching_assets_dicts,
|
||||||
|
latest_release_html_url,
|
||||||
|
)
|
||||||
|
|
||||||
elif strategy == "latest_github_tag" or strategy == "latest_gitlab_tag":
|
elif strategy == "latest_github_tag" or strategy == "latest_gitlab_tag":
|
||||||
if asset != "tarball":
|
if asset != "tarball":
|
||||||
|
@ -367,8 +392,12 @@ class AppAutoUpdater:
|
||||||
latest_commit = commits[0]
|
latest_commit = commits[0]
|
||||||
latest_tarball = api.url_for_ref(latest_commit["sha"], RefType.commits)
|
latest_tarball = api.url_for_ref(latest_commit["sha"], RefType.commits)
|
||||||
# Let's have the version as something like "2023.01.23"
|
# Let's have the version as something like "2023.01.23"
|
||||||
latest_commit_date = datetime.strptime(latest_commit["commit"]["author"]["date"][:10], "%Y-%m-%d")
|
latest_commit_date = datetime.strptime(
|
||||||
version_format = infos.get("autoupdate", {}).get("force_version", "%Y.%m.%d")
|
latest_commit["commit"]["author"]["date"][:10], "%Y-%m-%d"
|
||||||
|
)
|
||||||
|
version_format = infos.get("autoupdate", {}).get(
|
||||||
|
"force_version", "%Y.%m.%d"
|
||||||
|
)
|
||||||
latest_version = latest_commit_date.strftime(version_format)
|
latest_version = latest_commit_date.strftime(version_format)
|
||||||
|
|
||||||
return latest_version, latest_tarball
|
return latest_version, latest_tarball
|
||||||
|
@ -376,7 +405,6 @@ class AppAutoUpdater:
|
||||||
def replace_version_and_asset_in_manifest(
|
def replace_version_and_asset_in_manifest(
|
||||||
self, content, new_version, new_assets_urls, current_assets, is_main
|
self, content, new_version, new_assets_urls, current_assets, is_main
|
||||||
):
|
):
|
||||||
|
|
||||||
if isinstance(new_assets_urls, str):
|
if isinstance(new_assets_urls, str):
|
||||||
sha256 = sha256_of_remote_file(new_assets_urls)
|
sha256 = sha256_of_remote_file(new_assets_urls)
|
||||||
elif isinstance(new_assets_urls, dict):
|
elif isinstance(new_assets_urls, dict):
|
||||||
|
@ -387,7 +415,7 @@ class AppAutoUpdater:
|
||||||
if is_main:
|
if is_main:
|
||||||
|
|
||||||
def repl(m):
|
def repl(m):
|
||||||
return m.group(1) + new_version + "~ynh1\""
|
return m.group(1) + new_version + '~ynh1"'
|
||||||
|
|
||||||
content = re.sub(
|
content = re.sub(
|
||||||
r"(\s*version\s*=\s*[\"\'])([\d\.]+)(\~ynh\d+[\"\'])", repl, content
|
r"(\s*version\s*=\s*[\"\'])([\d\.]+)(\~ynh\d+[\"\'])", repl, content
|
||||||
|
@ -412,7 +440,8 @@ def progressbar(it, prefix="", size=60, file=sys.stdout):
|
||||||
name += " "
|
name += " "
|
||||||
x = int(size * j / count)
|
x = int(size * j / count)
|
||||||
file.write(
|
file.write(
|
||||||
"\n%s[%s%s] %i/%i %s\n" % (prefix, "#" * x, "." * (size - x), j, count, name)
|
"\n%s[%s%s] %i/%i %s\n"
|
||||||
|
% (prefix, "#" * x, "." * (size - x), j, count, name)
|
||||||
)
|
)
|
||||||
file.flush()
|
file.flush()
|
||||||
|
|
||||||
|
@ -432,14 +461,15 @@ def paste_on_haste(data):
|
||||||
TIMEOUT = 3
|
TIMEOUT = 3
|
||||||
try:
|
try:
|
||||||
url = SERVER_URL + "/documents"
|
url = SERVER_URL + "/documents"
|
||||||
response = requests.post(url, data=data.encode('utf-8'), timeout=TIMEOUT)
|
response = requests.post(url, data=data.encode("utf-8"), timeout=TIMEOUT)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
dockey = response.json()['key']
|
dockey = response.json()["key"]
|
||||||
return SERVER_URL + "/raw/" + dockey
|
return SERVER_URL + "/raw/" + dockey
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
print("\033[31mError: {}\033[0m".format(e))
|
print("\033[31mError: {}\033[0m".format(e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
args = [arg for arg in sys.argv[1:] if arg != "--commit-and-create-PR"]
|
args = [arg for arg in sys.argv[1:] if arg != "--commit-and-create-PR"]
|
||||||
|
|
||||||
|
@ -455,6 +485,7 @@ if __name__ == "__main__":
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
apps_failed.append(app)
|
apps_failed.append(app)
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
t = traceback.format_exc()
|
t = traceback.format_exc()
|
||||||
apps_failed_details[app] = t
|
apps_failed_details[app] = t
|
||||||
print(t)
|
print(t)
|
||||||
|
@ -465,8 +496,15 @@ if __name__ == "__main__":
|
||||||
if apps_failed:
|
if apps_failed:
|
||||||
print(f"Apps failed: {', '.join(apps_failed)}")
|
print(f"Apps failed: {', '.join(apps_failed)}")
|
||||||
if os.path.exists("/usr/bin/sendxmpppy"):
|
if os.path.exists("/usr/bin/sendxmpppy"):
|
||||||
paste = '\n=========\n'.join([app + "\n-------\n" + trace + "\n\n" for app, trace in apps_failed_details.items()])
|
paste = "\n=========\n".join(
|
||||||
paste_url = paste_on_haste(paste)
|
[
|
||||||
os.system(f"/usr/bin/sendxmpppy 'Failed to run the source auto-update for : {', '.join(apps_failed)}. Please run manually the `autoupdate_app_sources.py` script on these apps to debug what is happening! Debug log : {paste_url}'")
|
app + "\n-------\n" + trace + "\n\n"
|
||||||
|
for app, trace in apps_failed_details.items()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
paste_url = paste_on_haste(paste)
|
||||||
|
os.system(
|
||||||
|
f"/usr/bin/sendxmpppy 'Failed to run the source auto-update for : {', '.join(apps_failed)}. Please run manually the `autoupdate_app_sources.py` script on these apps to debug what is happening! Debug log : {paste_url}'"
|
||||||
|
)
|
||||||
if apps_updated:
|
if apps_updated:
|
||||||
print(f"Apps updated: {', '.join(apps_updated)}")
|
print(f"Apps updated: {', '.join(apps_updated)}")
|
||||||
|
|
|
@ -37,6 +37,12 @@ def get_wishlist() -> Dict[str, Dict[str, str]]:
|
||||||
return toml.load(wishlist_path)
|
return toml.load(wishlist_path)
|
||||||
|
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def get_graveyard() -> Dict[str, Dict[str, str]]:
|
||||||
|
wishlist_path = APPS_ROOT / "graveyard.toml"
|
||||||
|
return toml.load(wishlist_path)
|
||||||
|
|
||||||
|
|
||||||
def validate_schema() -> Generator[str, None, None]:
|
def validate_schema() -> Generator[str, None, None]:
|
||||||
with open(APPS_ROOT / "schemas" / "apps.toml.schema.json", encoding="utf-8") as file:
|
with open(APPS_ROOT / "schemas" / "apps.toml.schema.json", encoding="utf-8") as file:
|
||||||
apps_catalog_schema = json.load(file)
|
apps_catalog_schema = json.load(file)
|
||||||
|
@ -50,9 +56,6 @@ def check_app(app: str, infos: Dict[str, Any]) -> Generator[Tuple[str, bool], No
|
||||||
yield "state is missing", True
|
yield "state is missing", True
|
||||||
return
|
return
|
||||||
|
|
||||||
if infos["state"] != "working":
|
|
||||||
return
|
|
||||||
|
|
||||||
# validate that the app is not (anymore?) in the wishlist
|
# validate that the app is not (anymore?) in the wishlist
|
||||||
# we use fuzzy matching because the id in catalog may not be the same exact id as in the wishlist
|
# we use fuzzy matching because the id in catalog may not be the same exact id as in the wishlist
|
||||||
# some entries are ignore-hard-coded, because e.g. radarr an readarr are really different apps...
|
# some entries are ignore-hard-coded, because e.g. radarr an readarr are really different apps...
|
||||||
|
@ -66,6 +69,16 @@ def check_app(app: str, infos: Dict[str, Any]) -> Generator[Tuple[str, bool], No
|
||||||
if wishlist_matches:
|
if wishlist_matches:
|
||||||
yield f"app seems to be listed in wishlist: {wishlist_matches}", True
|
yield f"app seems to be listed in wishlist: {wishlist_matches}", True
|
||||||
|
|
||||||
|
ignored_graveyard_entries = ["mailman"]
|
||||||
|
graveyard_matches = [
|
||||||
|
grave
|
||||||
|
for grave in get_graveyard()
|
||||||
|
if grave not in ignored_graveyard_entries
|
||||||
|
and SequenceMatcher(None, app, grave).ratio() > 0.9
|
||||||
|
]
|
||||||
|
if graveyard_matches:
|
||||||
|
yield f"app seems to be listed in graveyard: {graveyard_matches}", True
|
||||||
|
|
||||||
repo_name = infos.get("url", "").split("/")[-1]
|
repo_name = infos.get("url", "").split("/")[-1]
|
||||||
if repo_name != f"{app}_ynh":
|
if repo_name != f"{app}_ynh":
|
||||||
yield f"repo name should be {app}_ynh, not in {repo_name}", True
|
yield f"repo name should be {app}_ynh, not in {repo_name}", True
|
||||||
|
|
365
wishlist.toml
|
@ -20,7 +20,7 @@ website = "https://ajenti.org"
|
||||||
name = "Akaunting"
|
name = "Akaunting"
|
||||||
description = "Manage payments/invoices/expenses"
|
description = "Manage payments/invoices/expenses"
|
||||||
upstream = "https://github.com/akaunting/akaunting"
|
upstream = "https://github.com/akaunting/akaunting"
|
||||||
website = ""
|
website = "https://akaunting.com/"
|
||||||
|
|
||||||
[amara]
|
[amara]
|
||||||
name = "Amara"
|
name = "Amara"
|
||||||
|
@ -28,11 +28,17 @@ description = "Collaborative translation of subtitles for videosCollaborative tr
|
||||||
upstream = "https://gitlab.com/hanklank/amara-archive"
|
upstream = "https://gitlab.com/hanklank/amara-archive"
|
||||||
website = "https://amara.org"
|
website = "https://amara.org"
|
||||||
|
|
||||||
|
[amusewiki]
|
||||||
|
name = "Amusewiki"
|
||||||
|
description = "A library-oriented wiki engine and a powerful authoring, archiving and publishing platform."
|
||||||
|
upstream = "https://github.com/melmothx/amusewiki"
|
||||||
|
website = "https://amusewiki.org"
|
||||||
|
|
||||||
[anki-sync-server]
|
[anki-sync-server]
|
||||||
name = "Anki Sync Server"
|
name = "Anki Sync Server"
|
||||||
description = "a personal Anki server"
|
description = "a personal Anki server"
|
||||||
upstream = "https://github.com/ankicommunity/anki-sync-server"
|
upstream = "https://github.com/ankicommunity/anki-sync-server"
|
||||||
website = ""
|
website = "https://apps.ankiweb.net/"
|
||||||
|
|
||||||
[anonaddy]
|
[anonaddy]
|
||||||
name = "AnonAddy"
|
name = "AnonAddy"
|
||||||
|
@ -112,11 +118,18 @@ description = "No-code database tool, alternative to Airtable"
|
||||||
upstream = "https://gitlab.com/bramw/baserow"
|
upstream = "https://gitlab.com/bramw/baserow"
|
||||||
website = "https://baserow.io/"
|
website = "https://baserow.io/"
|
||||||
|
|
||||||
|
[bearblog]
|
||||||
|
name = "Bearblog"
|
||||||
|
description = "Free, no-nonsense, super-fast blogging"
|
||||||
|
upstream = "https://github.com/HermanMartinus/bearblog/"
|
||||||
|
website = "https://bearblog.dev/"
|
||||||
|
|
||||||
[beatbump]
|
[beatbump]
|
||||||
name = "Beatbump"
|
name = "Beatbump"
|
||||||
description = "An alternative frontend for YouTube Music"
|
description = "An alternative frontend for YouTube Music"
|
||||||
upstream = "https://github.com/snuffyDev/Beatbump"
|
upstream = "https://github.com/snuffyDev/Beatbump"
|
||||||
website = "https://beatbump.ml/home"
|
website = "https://beatbump.ml/home"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/beatbump_ynh"
|
||||||
|
|
||||||
[beeper]
|
[beeper]
|
||||||
name = "Beeper"
|
name = "Beeper"
|
||||||
|
@ -136,6 +149,12 @@ description = "Web conferencing system"
|
||||||
upstream = "https://github.com/bigbluebutton/bigbluebutton"
|
upstream = "https://github.com/bigbluebutton/bigbluebutton"
|
||||||
website = "https://bigbluebutton.org"
|
website = "https://bigbluebutton.org"
|
||||||
|
|
||||||
|
[birdsitelive]
|
||||||
|
name = "BirdsiteLive"
|
||||||
|
description = "ActivityPub bridge from Twitter"
|
||||||
|
upstream = "https://github.com/NicolasConstant/BirdsiteLive"
|
||||||
|
website = ""
|
||||||
|
|
||||||
[bitcartcc]
|
[bitcartcc]
|
||||||
name = "BitcartCC"
|
name = "BitcartCC"
|
||||||
description = "All-in-one cryptocurrency solution"
|
description = "All-in-one cryptocurrency solution"
|
||||||
|
@ -152,7 +171,7 @@ website = "https://bitmessage.org/"
|
||||||
name = "Blynk"
|
name = "Blynk"
|
||||||
description = "Blynk library for embedded hardware. Works with Arduino, ESP8266, Raspberry Pi, Intel Edison/Galileo, LinkIt ONE, Particle Core/Photon, Energia, ARM mbed, etc."
|
description = "Blynk library for embedded hardware. Works with Arduino, ESP8266, Raspberry Pi, Intel Edison/Galileo, LinkIt ONE, Particle Core/Photon, Energia, ARM mbed, etc."
|
||||||
upstream = "https://github.com/blynkkk/blynk-library"
|
upstream = "https://github.com/blynkkk/blynk-library"
|
||||||
website = ""
|
website = "https://blynk.io/"
|
||||||
|
|
||||||
[boinc]
|
[boinc]
|
||||||
name = "BOINC"
|
name = "BOINC"
|
||||||
|
@ -194,13 +213,13 @@ website = "https://cal.com/"
|
||||||
name = "changedetection.io"
|
name = "changedetection.io"
|
||||||
description = "Monitor changes in web pages"
|
description = "Monitor changes in web pages"
|
||||||
upstream = "https://github.com/dgtlmoon/changedetection.io"
|
upstream = "https://github.com/dgtlmoon/changedetection.io"
|
||||||
website = ""
|
website = "https://changedetection.io/"
|
||||||
|
|
||||||
[chaskiq]
|
[chaskiq]
|
||||||
name = "Chaskiq"
|
name = "Chaskiq"
|
||||||
description = "A full featured Live Chat, Support & Marketing platform, alternative to Intercom, Drift, Crisp"
|
description = "A full featured Live Chat, Support & Marketing platform, alternative to Intercom, Drift, Crisp"
|
||||||
upstream = "https://github.com/chaskiq/chaskiq"
|
upstream = "https://github.com/chaskiq/chaskiq"
|
||||||
website = ""
|
website = "https://chaskiq.io/"
|
||||||
|
|
||||||
[chatterbox]
|
[chatterbox]
|
||||||
name = "Chatterbox"
|
name = "Chatterbox"
|
||||||
|
@ -232,6 +251,12 @@ description = "A tool for making open data websites"
|
||||||
upstream = "https://github.com/ckan/ckan"
|
upstream = "https://github.com/ckan/ckan"
|
||||||
website = "https://ckan.org/"
|
website = "https://ckan.org/"
|
||||||
|
|
||||||
|
[claper]
|
||||||
|
name = "Claper"
|
||||||
|
description = "Claper turns your presentations into an interactive, engaging and exciting experience."
|
||||||
|
upstream = "https://github.com/ClaperCo/claper"
|
||||||
|
website = "https://claper.co/"
|
||||||
|
|
||||||
[clearflask]
|
[clearflask]
|
||||||
name = "ClearFlask"
|
name = "ClearFlask"
|
||||||
description = "Ideation Tool for Feedback, Roadmap and Announcements"
|
description = "Ideation Tool for Feedback, Roadmap and Announcements"
|
||||||
|
@ -244,6 +269,12 @@ description = "CloudTube front-end for YouTube"
|
||||||
upstream = "https://git.sr.ht/~cadence/cloudtube"
|
upstream = "https://git.sr.ht/~cadence/cloudtube"
|
||||||
website = "https://tube.cadence.moe/"
|
website = "https://tube.cadence.moe/"
|
||||||
|
|
||||||
|
[cobalt]
|
||||||
|
name = "Cobalt"
|
||||||
|
description = "Simple Media downloader GUI"
|
||||||
|
upstream = "https://github.com/wukko/cobalt"
|
||||||
|
website = "https://cobalt.tools/"
|
||||||
|
|
||||||
[commafeed]
|
[commafeed]
|
||||||
name = "Commafeed"
|
name = "Commafeed"
|
||||||
description = "RSS reader"
|
description = "RSS reader"
|
||||||
|
@ -267,6 +298,7 @@ name = "Coquelicot"
|
||||||
description = "A “one-click” file sharing web application"
|
description = "A “one-click” file sharing web application"
|
||||||
upstream = ""
|
upstream = ""
|
||||||
website = "https://coquelicot.potager.org/"
|
website = "https://coquelicot.potager.org/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/coquelicot_ynh"
|
||||||
|
|
||||||
[counter]
|
[counter]
|
||||||
name = "Counter"
|
name = "Counter"
|
||||||
|
@ -305,11 +337,23 @@ upstream = "https://github.com/mguessan/davmail"
|
||||||
website = "http://davmail.sourceforge.net/"
|
website = "http://davmail.sourceforge.net/"
|
||||||
|
|
||||||
[digibuzzer]
|
[digibuzzer]
|
||||||
name = "DIGIBUZZER"
|
name = "Digibuzzer"
|
||||||
description = "pour jouer autour d'un buzzer connecté"
|
description = "pour jouer autour d'un buzzer connecté"
|
||||||
upstream = "https://codeberg.org/ladigitale/digibuzzer"
|
upstream = "https://codeberg.org/ladigitale/digibuzzer"
|
||||||
website = "https://digibuzzer.app/"
|
website = "https://digibuzzer.app/"
|
||||||
|
|
||||||
|
[digishare]
|
||||||
|
name = "Digishare"
|
||||||
|
description = "pour partager des fichiers avec des appareils proches"
|
||||||
|
upstream = "https://codeberg.org/ladigitale/digishare"
|
||||||
|
website = "https://ladigitale.dev/digishare/"
|
||||||
|
|
||||||
|
[digistorm]
|
||||||
|
name = "Digistorm"
|
||||||
|
description = "pour créer des remue-méninges, des questionnaires, etc."
|
||||||
|
upstream = "https://codeberg.org/ladigitale/digistorm"
|
||||||
|
website = "https://digistorm.app/"
|
||||||
|
|
||||||
[directus]
|
[directus]
|
||||||
name = "Directus"
|
name = "Directus"
|
||||||
description = "Real-time API and intuitive no-code data collaboration app for any SQL database"
|
description = "Real-time API and intuitive no-code data collaboration app for any SQL database"
|
||||||
|
@ -332,7 +376,7 @@ website = ""
|
||||||
name = "Docspell"
|
name = "Docspell"
|
||||||
description = "Simple document organizer"
|
description = "Simple document organizer"
|
||||||
upstream = "https://github.com/eikek/docspell"
|
upstream = "https://github.com/eikek/docspell"
|
||||||
website = ""
|
website = "https://docspell.org/"
|
||||||
|
|
||||||
[docusaurus]
|
[docusaurus]
|
||||||
name = "Docusaurus"
|
name = "Docusaurus"
|
||||||
|
@ -340,6 +384,12 @@ description = "Static site generator/SPA to build documentations"
|
||||||
upstream = "https://github.com/facebook/docusaurus"
|
upstream = "https://github.com/facebook/docusaurus"
|
||||||
website = ""
|
website = ""
|
||||||
|
|
||||||
|
[docuseal]
|
||||||
|
name = "DocuSeal"
|
||||||
|
description = "Create, fill, and sign digital documents"
|
||||||
|
upstream = "https://github.com/docusealco/docuseal"
|
||||||
|
website = "https://www.docuseal.co/"
|
||||||
|
|
||||||
[dokos]
|
[dokos]
|
||||||
name = "Dokos"
|
name = "Dokos"
|
||||||
description = "Plateforme de gestion pour votre Entreprise. Adaptation française d'ERPNext."
|
description = "Plateforme de gestion pour votre Entreprise. Adaptation française d'ERPNext."
|
||||||
|
@ -400,6 +450,12 @@ description = "Modern intranet, social network, community management platform, c
|
||||||
upstream = "https://github.com/exoplatform/"
|
upstream = "https://github.com/exoplatform/"
|
||||||
website = "https://www.exoplatform.com"
|
website = "https://www.exoplatform.com"
|
||||||
|
|
||||||
|
[faircamp]
|
||||||
|
name = "Faircamp"
|
||||||
|
description = "Static site generator for audio artists and producers"
|
||||||
|
upstream = "https://codeberg.org/simonrepp/faircamp"
|
||||||
|
website = "https://simonrepp.com/faircamp/"
|
||||||
|
|
||||||
[farside]
|
[farside]
|
||||||
name = "Farside"
|
name = "Farside"
|
||||||
description = "A redirecting service for FOSS alternative frontends"
|
description = "A redirecting service for FOSS alternative frontends"
|
||||||
|
@ -466,11 +522,11 @@ description = "Online service aggregator hub"
|
||||||
upstream = "https://github.com/mozilla/togetherjs"
|
upstream = "https://github.com/mozilla/togetherjs"
|
||||||
website = ""
|
website = ""
|
||||||
|
|
||||||
[freescout]
|
[frigate]
|
||||||
name = "Freescout"
|
name = "Frigate"
|
||||||
description = "Helpdesk & Shared Mailbox"
|
description = "Local NVR designed for Home Assistant with AI object detection"
|
||||||
upstream = "https://github.com/freescout-helpdesk/freescout"
|
upstream = "https://github.com/blakeblackshear/frigate"
|
||||||
website = "https://freescout.net/"
|
website = "https://frigate.video/"
|
||||||
|
|
||||||
[gatsby]
|
[gatsby]
|
||||||
name = "Gatsby"
|
name = "Gatsby"
|
||||||
|
@ -484,6 +540,18 @@ description = "Genealogy in a web interface"
|
||||||
upstream = "https://github.com/geneweb/geneweb"
|
upstream = "https://github.com/geneweb/geneweb"
|
||||||
website = "https://geneweb.tuxfamily.org"
|
website = "https://geneweb.tuxfamily.org"
|
||||||
|
|
||||||
|
[geovisio]
|
||||||
|
name = "GeoVisio"
|
||||||
|
description = "Self-hosting geo-located street pictures solution"
|
||||||
|
upstream = "https://gitlab.com/geovisio"
|
||||||
|
website = "https://geovisio.fr/"
|
||||||
|
|
||||||
|
[gladys-assistant]
|
||||||
|
name = "Gladys Assistant"
|
||||||
|
description = "A privacy-first, open-source home assistant."
|
||||||
|
upstream = "https://github.com/gladysassistant/gladys"
|
||||||
|
website = "https://gladysassistant.com/"
|
||||||
|
|
||||||
[goaccess]
|
[goaccess]
|
||||||
name = "Goaccess"
|
name = "Goaccess"
|
||||||
description = "Web log analyzer"
|
description = "Web log analyzer"
|
||||||
|
@ -507,12 +575,25 @@ name = "Gollum"
|
||||||
description = "A simple Git-powered wiki"
|
description = "A simple Git-powered wiki"
|
||||||
upstream = "https://github.com/gollum/gollum"
|
upstream = "https://github.com/gollum/gollum"
|
||||||
website = ""
|
website = ""
|
||||||
|
draft = "https://github.com/YunoHost-Apps/gollum_ynh"
|
||||||
|
|
||||||
|
[gothub]
|
||||||
|
name = "GotHub"
|
||||||
|
description = "An alternative front-end for GitHub, written in Go."
|
||||||
|
upstream = "https://codeberg.org/gothub/gothub"
|
||||||
|
website = "https://gothub.app/"
|
||||||
|
|
||||||
|
[gramps-web]
|
||||||
|
name = "Gramps Web"
|
||||||
|
description = "Collaborative genealogy, based on and interoperable with Gramps."
|
||||||
|
upstream = "https://github.com/gramps-project/Gramps.js"
|
||||||
|
website = "https://www.grampsweb.org/"
|
||||||
|
|
||||||
[granary]
|
[granary]
|
||||||
name = "Granary"
|
name = "Granary"
|
||||||
description = "💬 The social web translator"
|
description = "💬 The social web translator"
|
||||||
upstream = "https://github.com/snarfed/granary"
|
upstream = "https://github.com/snarfed/granary"
|
||||||
website = ""
|
website = "https://granary.io/"
|
||||||
|
|
||||||
[graphhopper]
|
[graphhopper]
|
||||||
name = "Graphhopper"
|
name = "Graphhopper"
|
||||||
|
@ -526,12 +607,6 @@ description = "A really simple end-user interface for your BigBlueButton server"
|
||||||
upstream = "https://github.com/bigbluebutton/greenlight"
|
upstream = "https://github.com/bigbluebutton/greenlight"
|
||||||
website = "https://blabla.aquilenet.fr/b"
|
website = "https://blabla.aquilenet.fr/b"
|
||||||
|
|
||||||
[grist]
|
|
||||||
name = "Grist"
|
|
||||||
description = "The evolution of spreadsheets"
|
|
||||||
upstream = "https://github.com/gristlabs/grist-core/"
|
|
||||||
website = "https://www.getgrist.com/"
|
|
||||||
|
|
||||||
[habitica]
|
[habitica]
|
||||||
name = "Habitica"
|
name = "Habitica"
|
||||||
description = "A habit tracker app which treats your goals like a Role Playing Game."
|
description = "A habit tracker app which treats your goals like a Role Playing Game."
|
||||||
|
@ -544,11 +619,17 @@ description = "Vehicle expense tracking system"
|
||||||
upstream = "https://github.com/akhilrex/hammond"
|
upstream = "https://github.com/akhilrex/hammond"
|
||||||
website = ""
|
website = ""
|
||||||
|
|
||||||
|
[hauk]
|
||||||
|
name = "Hauk"
|
||||||
|
description = "Realtime location sharing"
|
||||||
|
upstream = "https://github.com/bilde2910/Hauk"
|
||||||
|
website = ""
|
||||||
|
|
||||||
[helpy]
|
[helpy]
|
||||||
name = "Helpy"
|
name = "Helpy"
|
||||||
description = "A modern helpdesk customer support app, including knowledgebase, discussions and tickets"
|
description = "A modern helpdesk customer support app, including knowledgebase, discussions and tickets"
|
||||||
upstream = "https://github.com/helpyio/helpy"
|
upstream = "https://github.com/helpyio/helpy"
|
||||||
website = ""
|
website = "https://helpy.io/"
|
||||||
|
|
||||||
[hexo]
|
[hexo]
|
||||||
name = "Hexo"
|
name = "Hexo"
|
||||||
|
@ -594,10 +675,17 @@ website = "https://v2.hysteria.network/"
|
||||||
|
|
||||||
[icecast-2]
|
[icecast-2]
|
||||||
name = "Icecast 2"
|
name = "Icecast 2"
|
||||||
description = ""
|
description = "Streaming media server supporting Ogg, Opus, WebM and MP3 streams"
|
||||||
upstream = "https://gitlab.xiph.org/xiph/icecast-server/"
|
upstream = "https://gitlab.xiph.org/xiph/icecast-server/"
|
||||||
website = "https://www.icecast.org"
|
website = "https://www.icecast.org"
|
||||||
|
|
||||||
|
[immich]
|
||||||
|
name = "Immich"
|
||||||
|
description = "Self-hosted backup solution for photos and videos on mobile device. Alternative to Google Photo."
|
||||||
|
upstream = "https://github.com/immich-app/immich"
|
||||||
|
website = "https://immich.app/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/immich_ynh"
|
||||||
|
|
||||||
[infcloud]
|
[infcloud]
|
||||||
name = "InfCloud"
|
name = "InfCloud"
|
||||||
description = "A contacts, calendar and tasks web client for CalDAV and CardDAV"
|
description = "A contacts, calendar and tasks web client for CalDAV and CardDAV"
|
||||||
|
@ -616,6 +704,12 @@ description = "A collaborative resource mapper powered by open-knowledge, starti
|
||||||
upstream = "https://github.com/inventaire/inventaire"
|
upstream = "https://github.com/inventaire/inventaire"
|
||||||
website = "https://inventaire.io"
|
website = "https://inventaire.io"
|
||||||
|
|
||||||
|
[inventree]
|
||||||
|
name = "InvenTree"
|
||||||
|
description = "Inventory management system using Django/python with a nice interface."
|
||||||
|
upstream = "https://github.com/inventree/inventree"
|
||||||
|
website = "https://inventree.org/"
|
||||||
|
|
||||||
[invoiceplane]
|
[invoiceplane]
|
||||||
name = "InvoicePlane"
|
name = "InvoicePlane"
|
||||||
description = "Manage invoices, clients and payments."
|
description = "Manage invoices, clients and payments."
|
||||||
|
@ -627,12 +721,7 @@ name = "IPFS"
|
||||||
description = "Peer-to-peer hypermedia protocol"
|
description = "Peer-to-peer hypermedia protocol"
|
||||||
upstream = "https://github.com/ipfs/ipfs"
|
upstream = "https://github.com/ipfs/ipfs"
|
||||||
website = "https://ipfs.io"
|
website = "https://ipfs.io"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/ipfs_ynh"
|
||||||
[joplin]
|
|
||||||
name = "Joplin"
|
|
||||||
description = "Note taking and to-do application with synchronisation capabilities for Windows, macOS, Linux, Android and iOS."
|
|
||||||
upstream = "https://github.com/laurent22/joplin"
|
|
||||||
website = "https://joplin.cozic.net/"
|
|
||||||
|
|
||||||
[js-bin]
|
[js-bin]
|
||||||
name = "JS Bin"
|
name = "JS Bin"
|
||||||
|
@ -646,6 +735,12 @@ description = "Organize karaoke parties"
|
||||||
upstream = "https://github.com/bhj/karaoke-forever"
|
upstream = "https://github.com/bhj/karaoke-forever"
|
||||||
website = "https://www.karaoke-forever.com/"
|
website = "https://www.karaoke-forever.com/"
|
||||||
|
|
||||||
|
[khoj]
|
||||||
|
name = "Khoj"
|
||||||
|
description = "AI personal assistant accessible from Emacs, Obsidian or your Web browser"
|
||||||
|
upstream = "https://github.com/khoj-ai/khoj"
|
||||||
|
website = "https://khoj.dev/"
|
||||||
|
|
||||||
[kill-the-newsletter]
|
[kill-the-newsletter]
|
||||||
name = "Kill the newsletter"
|
name = "Kill the newsletter"
|
||||||
description = "Convert email newsletters to RSS feeds"
|
description = "Convert email newsletters to RSS feeds"
|
||||||
|
@ -657,6 +752,7 @@ name = "Kitchenowl"
|
||||||
description = "Grocery list and recipe manager"
|
description = "Grocery list and recipe manager"
|
||||||
upstream = "https://github.com/TomBursch/kitchenowl"
|
upstream = "https://github.com/TomBursch/kitchenowl"
|
||||||
website = "https://kitchenowl.org/"
|
website = "https://kitchenowl.org/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/kitchenowl_ynh"
|
||||||
|
|
||||||
[klaxon]
|
[klaxon]
|
||||||
name = "Klaxon"
|
name = "Klaxon"
|
||||||
|
@ -676,11 +772,29 @@ description = "Library system"
|
||||||
upstream = "https://git.koha-community.org/Koha-community/Koha"
|
upstream = "https://git.koha-community.org/Koha-community/Koha"
|
||||||
website = "https://koha-community.org/"
|
website = "https://koha-community.org/"
|
||||||
|
|
||||||
|
[koreader-sync-server]
|
||||||
|
name = "Koreader Sync Server"
|
||||||
|
description = "Synchronization service for Koreader devices"
|
||||||
|
upstream = "https://github.com/koreader/koreader-sync-server"
|
||||||
|
website = "https://koreader.rocks/"
|
||||||
|
|
||||||
|
[kutt-it]
|
||||||
|
name = "Kutt.it"
|
||||||
|
description = "Link shortener"
|
||||||
|
upstream = "https://github.com/thedevs-network/kutt"
|
||||||
|
website = "https://kutt.it/"
|
||||||
|
|
||||||
[l-atelier]
|
[l-atelier]
|
||||||
name = "L'atelier"
|
name = "L'atelier"
|
||||||
description = "A project management tool"
|
description = "A project management tool"
|
||||||
upstream = "https://github.com/jbl2024/latelier"
|
upstream = "https://github.com/jbl2024/latelier"
|
||||||
website = ""
|
website = "https://jbl2024.github.io/latelier-page/"
|
||||||
|
|
||||||
|
[lago]
|
||||||
|
name = "Lago"
|
||||||
|
description = "Lago is an open source billing API for product-led SaaS."
|
||||||
|
upstream = "https://github.com/getlago/lago"
|
||||||
|
website = "https://www.getlago.com/"
|
||||||
|
|
||||||
[lesspass]
|
[lesspass]
|
||||||
name = "LessPass"
|
name = "LessPass"
|
||||||
|
@ -694,6 +808,12 @@ description = "Radio Broadcast & Automation Platform"
|
||||||
upstream = "https://github.com/libretime/libretime"
|
upstream = "https://github.com/libretime/libretime"
|
||||||
website = "https://libretime.org/"
|
website = "https://libretime.org/"
|
||||||
|
|
||||||
|
[librum]
|
||||||
|
name = "Librum"
|
||||||
|
description = "Read and manage your e-books on any device."
|
||||||
|
upstream = "https://github.com/Librum-Reader/Librum"
|
||||||
|
website = "https://librumreader.com/"
|
||||||
|
|
||||||
[lichen]
|
[lichen]
|
||||||
name = "Lichen"
|
name = "Lichen"
|
||||||
description = "Gemtext to HTML translator"
|
description = "Gemtext to HTML translator"
|
||||||
|
@ -718,6 +838,12 @@ description = "Minimal, fast, and easy bookmark manager"
|
||||||
upstream = "https://github.com/sissbruecker/linkding"
|
upstream = "https://github.com/sissbruecker/linkding"
|
||||||
website = ""
|
website = ""
|
||||||
|
|
||||||
|
[linkwarden]
|
||||||
|
name = "Linkwarden"
|
||||||
|
description = "Collaborative bookmark manager"
|
||||||
|
upstream = "https://github.com/linkwarden/linkwarden"
|
||||||
|
website = "https://linkwarden.app/"
|
||||||
|
|
||||||
[liquidsoap]
|
[liquidsoap]
|
||||||
name = "LiquidSoap"
|
name = "LiquidSoap"
|
||||||
description = "Audio and video streaming language"
|
description = "Audio and video streaming language"
|
||||||
|
@ -734,7 +860,7 @@ website = "https://localai.io"
|
||||||
name = "LocomotiveCMS"
|
name = "LocomotiveCMS"
|
||||||
description = "A platform to create, publish and edit sites"
|
description = "A platform to create, publish and edit sites"
|
||||||
upstream = "https://github.com/locomotivecms/engine"
|
upstream = "https://github.com/locomotivecms/engine"
|
||||||
website = ""
|
website = "https://www.locomotivecms.com/"
|
||||||
|
|
||||||
[logitech-media-server]
|
[logitech-media-server]
|
||||||
name = "Logitech Media Server"
|
name = "Logitech Media Server"
|
||||||
|
@ -772,12 +898,24 @@ description = "Music scrobble database, alternative to Last.fm"
|
||||||
upstream = "https://github.com/krateng/maloja"
|
upstream = "https://github.com/krateng/maloja"
|
||||||
website = "https://maloja.krateng.ch"
|
website = "https://maloja.krateng.ch"
|
||||||
|
|
||||||
|
[maloja]
|
||||||
|
name = "Maloja"
|
||||||
|
description = "Simple self-hosted music scrobble database to create personal listening statistics."
|
||||||
|
upstream = "https://github.com/krateng/maloja"
|
||||||
|
website = "https://maloja.krateng.ch/"
|
||||||
|
|
||||||
[mautrix-discord]
|
[mautrix-discord]
|
||||||
name = "Mautrix-Discord"
|
name = "Mautrix-Discord"
|
||||||
description = "Matrix bridge for Discord"
|
description = "Matrix bridge for Discord"
|
||||||
upstream = "https://github.com/mautrix/discord"
|
upstream = "https://github.com/mautrix/discord"
|
||||||
website = ""
|
website = ""
|
||||||
|
|
||||||
|
[mayan-edms]
|
||||||
|
name = "Mayan-EDMS"
|
||||||
|
description = "Document management system"
|
||||||
|
upstream = "https://gitlab.com/mayan-edms/mayan-edms"
|
||||||
|
website = "https://www.mayan-edms.com/"
|
||||||
|
|
||||||
[mealie]
|
[mealie]
|
||||||
name = "Mealie"
|
name = "Mealie"
|
||||||
description = "Recipe manager and meal planner"
|
description = "Recipe manager and meal planner"
|
||||||
|
@ -789,12 +927,14 @@ name = "Mediagoblin"
|
||||||
description = "Video streaming platform"
|
description = "Video streaming platform"
|
||||||
upstream = "https://savannah.gnu.org/projects/mediagoblin"
|
upstream = "https://savannah.gnu.org/projects/mediagoblin"
|
||||||
website = "https://mediagoblin.org/"
|
website = "https://mediagoblin.org/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/mediagoblin_ynh"
|
||||||
|
|
||||||
[medusa]
|
[medusa]
|
||||||
name = "Medusa"
|
name = "Medusa"
|
||||||
description = "Automatic TV shows downloader"
|
description = "Automatic TV shows downloader"
|
||||||
upstream = ""
|
upstream = "https://github.com/pymedusa/Medusa"
|
||||||
website = "https://pymedusa.com/"
|
website = "https://pymedusa.com/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/medusa_ynh"
|
||||||
|
|
||||||
[megaglest]
|
[megaglest]
|
||||||
name = "Megaglest"
|
name = "Megaglest"
|
||||||
|
@ -812,7 +952,7 @@ website = "https://meshery.io/"
|
||||||
name = "microblog.pub"
|
name = "microblog.pub"
|
||||||
description = "A single-user ActivityPub-powered microblog."
|
description = "A single-user ActivityPub-powered microblog."
|
||||||
upstream = "https://github.com/tsileo/microblog.pub"
|
upstream = "https://github.com/tsileo/microblog.pub"
|
||||||
website = ""
|
website = "https://microblog.pub/"
|
||||||
|
|
||||||
[mindustry]
|
[mindustry]
|
||||||
name = "Mindustry"
|
name = "Mindustry"
|
||||||
|
@ -826,6 +966,12 @@ description = "Messaging over Gemini"
|
||||||
upstream = "https://git.sr.ht/~lem/misfin"
|
upstream = "https://git.sr.ht/~lem/misfin"
|
||||||
website = "gemini://misfin.org/"
|
website = "gemini://misfin.org/"
|
||||||
|
|
||||||
|
[mixpost]
|
||||||
|
name = "Mixpost"
|
||||||
|
description = "Self-hosted social media management"
|
||||||
|
upstream = "https://github.com/inovector/mixpost"
|
||||||
|
website = "https://mixpost.app/"
|
||||||
|
|
||||||
[mkdocs]
|
[mkdocs]
|
||||||
name = "MkDocs"
|
name = "MkDocs"
|
||||||
description = "A fast, simple and downright site generator, building project documentation."
|
description = "A fast, simple and downright site generator, building project documentation."
|
||||||
|
@ -838,12 +984,6 @@ description = "Mail hosting made simple"
|
||||||
upstream = "https://github.com/modoboa/modoboa"
|
upstream = "https://github.com/modoboa/modoboa"
|
||||||
website = "https://modoboa.org"
|
website = "https://modoboa.org"
|
||||||
|
|
||||||
[motioneye]
|
|
||||||
name = "MotionEye"
|
|
||||||
description = "A web frontend for the motion daemon"
|
|
||||||
upstream = "https://github.com/ccrisan/motioneye"
|
|
||||||
website = ""
|
|
||||||
|
|
||||||
[nebula]
|
[nebula]
|
||||||
name = "Nebula"
|
name = "Nebula"
|
||||||
description = "Scalable overlay networking tool with a focus on performance, simplicity and security."
|
description = "Scalable overlay networking tool with a focus on performance, simplicity and security."
|
||||||
|
@ -866,7 +1006,7 @@ website = "https://netlifycms.org/"
|
||||||
name = "Netrunner"
|
name = "Netrunner"
|
||||||
description = "A card game in a cyberpunk universe"
|
description = "A card game in a cyberpunk universe"
|
||||||
upstream = "https://github.com/mtgred/netrunner"
|
upstream = "https://github.com/mtgred/netrunner"
|
||||||
website = ""
|
website = "https://www.jinteki.net/"
|
||||||
|
|
||||||
[newsblur]
|
[newsblur]
|
||||||
name = "NewsBlur"
|
name = "NewsBlur"
|
||||||
|
@ -902,7 +1042,7 @@ website = "https://demo.officelife.io/"
|
||||||
name = "OhMyForm"
|
name = "OhMyForm"
|
||||||
description = "Alternative to TypeForm, TellForm, or Google Forms"
|
description = "Alternative to TypeForm, TellForm, or Google Forms"
|
||||||
upstream = "https://github.com/ohmyform/ohmyform"
|
upstream = "https://github.com/ohmyform/ohmyform"
|
||||||
website = ""
|
website = "https://ohmyform.com/"
|
||||||
|
|
||||||
[omnivore]
|
[omnivore]
|
||||||
name = "Omnivore"
|
name = "Omnivore"
|
||||||
|
@ -922,12 +1062,25 @@ description = "Shopping cart system. An online e-commerce solution."
|
||||||
upstream = "https://github.com/opencart/opencart"
|
upstream = "https://github.com/opencart/opencart"
|
||||||
website = "https://www.opencart.com"
|
website = "https://www.opencart.com"
|
||||||
|
|
||||||
|
[opencast]
|
||||||
|
draft = "https://github.com/YunoHost-Apps/opencast_ynh"
|
||||||
|
name = "opencast"
|
||||||
|
description = "Flexible, reliable, and scalable open source video management system for academic institution"
|
||||||
|
upstream = "https://github.com/opencast/opencast/"
|
||||||
|
website = "https://opencast.org/"
|
||||||
|
|
||||||
[openhab]
|
[openhab]
|
||||||
name = "openHAB"
|
name = "openHAB"
|
||||||
description = "Smart home platform"
|
description = "Smart home platform"
|
||||||
upstream = "https://github.com/openhab/openhab-webui"
|
upstream = "https://github.com/openhab/openhab-webui"
|
||||||
website = "https://www.openhab.org/"
|
website = "https://www.openhab.org/"
|
||||||
|
|
||||||
|
[opensign]
|
||||||
|
name = "OpenSign"
|
||||||
|
description = "DocuSign alternative, for signing and annotating PDF files"
|
||||||
|
upstream = "https://github.com/OpenSignLabs/OpenSign"
|
||||||
|
website = "https://www.opensignlabs.com/"
|
||||||
|
|
||||||
[organizr]
|
[organizr]
|
||||||
name = "organizr"
|
name = "organizr"
|
||||||
description = "Organizr allows you to setup \"Tabs\" that will be loaded all in one webpage"
|
description = "Organizr allows you to setup \"Tabs\" that will be loaded all in one webpage"
|
||||||
|
@ -938,7 +1091,7 @@ website = "https://docs.organizr.app/"
|
||||||
name = "OSRM"
|
name = "OSRM"
|
||||||
description = "Routing Machine - C++ backend"
|
description = "Routing Machine - C++ backend"
|
||||||
upstream = "https://github.com/Project-OSRM/osrm-backend"
|
upstream = "https://github.com/Project-OSRM/osrm-backend"
|
||||||
website = ""
|
website = "https://project-osrm.org/"
|
||||||
|
|
||||||
[otobo]
|
[otobo]
|
||||||
name = "Otobo"
|
name = "Otobo"
|
||||||
|
@ -970,6 +1123,12 @@ description = "Password manager"
|
||||||
upstream = "https://github.com/passbolt/passbolt_docker"
|
upstream = "https://github.com/passbolt/passbolt_docker"
|
||||||
website = "https://www.passbolt.com"
|
website = "https://www.passbolt.com"
|
||||||
|
|
||||||
|
[peer-calls]
|
||||||
|
name = "peer-calls"
|
||||||
|
description = "WebRTC group peer to peer video calls for everyone"
|
||||||
|
upstream = "https://github.com/peer-calls/peer-calls"
|
||||||
|
website = "https://peercalls.com/"
|
||||||
|
|
||||||
[penpot]
|
[penpot]
|
||||||
name = "Penpot"
|
name = "Penpot"
|
||||||
description = "Design Freedom for Teams"
|
description = "Design Freedom for Teams"
|
||||||
|
@ -981,12 +1140,13 @@ name = "Peppermint"
|
||||||
description = "A central hub for your help desk. A powerfully easy system for tracking, prioritising, and solving customer support tickets"
|
description = "A central hub for your help desk. A powerfully easy system for tracking, prioritising, and solving customer support tickets"
|
||||||
upstream = "https://github.com/Peppermint-Lab/peppermint"
|
upstream = "https://github.com/Peppermint-Lab/peppermint"
|
||||||
website = "https://peppermint.sh/"
|
website = "https://peppermint.sh/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/peppermint_ynh"
|
||||||
|
|
||||||
[personal-management-system]
|
[personal-management-system]
|
||||||
name = "personal-management-system"
|
name = "personal-management-system"
|
||||||
description = "Your web application for managing personal data."
|
description = "Your web application for managing personal data."
|
||||||
upstream = "https://github.com/Volmarg/personal-management-system"
|
upstream = "https://github.com/Volmarg/personal-management-system"
|
||||||
website = ""
|
website = "http://personal-management-system.pl/"
|
||||||
|
|
||||||
[phorge]
|
[phorge]
|
||||||
name = "Phorge"
|
name = "Phorge"
|
||||||
|
@ -1005,6 +1165,7 @@ name = "PIA"
|
||||||
description = "A tool to help carrying out Privacy Impact Assessments"
|
description = "A tool to help carrying out Privacy Impact Assessments"
|
||||||
upstream = "https://github.com/LINCnil/pia"
|
upstream = "https://github.com/LINCnil/pia"
|
||||||
website = ""
|
website = ""
|
||||||
|
draft = "https://github.com/YunoHost-Apps/pia_ynh"
|
||||||
|
|
||||||
[picsur]
|
[picsur]
|
||||||
name = "Picsur"
|
name = "Picsur"
|
||||||
|
@ -1030,18 +1191,18 @@ description = "Project planning tool"
|
||||||
upstream = "https://github.com/makeplane/plane"
|
upstream = "https://github.com/makeplane/plane"
|
||||||
website = "https://plane.so/"
|
website = "https://plane.so/"
|
||||||
|
|
||||||
[planka]
|
|
||||||
name = "Planka"
|
|
||||||
description = "Kanban board for workgroups."
|
|
||||||
upstream = "https://github.com/plankanban/planka"
|
|
||||||
website = "https://planka.app/"
|
|
||||||
|
|
||||||
[plausible-analytics]
|
[plausible-analytics]
|
||||||
name = "Plausible Analytics"
|
name = "Plausible Analytics"
|
||||||
description = "Privacy-friendly web analytics (alternative to Google Analytics)"
|
description = "Privacy-friendly web analytics (alternative to Google Analytics)"
|
||||||
upstream = "https://github.com/plausible/analytics"
|
upstream = "https://github.com/plausible/analytics"
|
||||||
website = "https://plausible.io"
|
website = "https://plausible.io"
|
||||||
|
|
||||||
|
[polis]
|
||||||
|
name = "Polis"
|
||||||
|
description = "Gathers and analyzes what large groups of people think in their own words. Creates shared decisions."
|
||||||
|
upstream = "https://github.com/compdemocracy/polis"
|
||||||
|
website = "https://pol.is"
|
||||||
|
|
||||||
[pretix]
|
[pretix]
|
||||||
name = "pretix"
|
name = "pretix"
|
||||||
description = "All-in-one ticketing software"
|
description = "All-in-one ticketing software"
|
||||||
|
@ -1071,6 +1232,7 @@ name = "Proxigram"
|
||||||
description = "Front-end for Instagram, providing also RSS"
|
description = "Front-end for Instagram, providing also RSS"
|
||||||
upstream = "https://codeberg.org/ThePenguinDev/Proxigram"
|
upstream = "https://codeberg.org/ThePenguinDev/Proxigram"
|
||||||
website = ""
|
website = ""
|
||||||
|
draft = "https://github.com/YunoHost-Apps/proxigram_ynh"
|
||||||
|
|
||||||
[psono]
|
[psono]
|
||||||
name = "Psono"
|
name = "Psono"
|
||||||
|
@ -1080,9 +1242,10 @@ website = "https://psono.com/"
|
||||||
|
|
||||||
[pterodactyl]
|
[pterodactyl]
|
||||||
name = "Pterodactyl"
|
name = "Pterodactyl"
|
||||||
description = ""
|
description = "Game server management panel"
|
||||||
upstream = ""
|
upstream = "https://github.com/pterodactyl/panel"
|
||||||
website = "https://pterodactyl.io/"
|
website = "https://pterodactyl.io/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/pterodactyl_ynh"
|
||||||
|
|
||||||
[qgis-server]
|
[qgis-server]
|
||||||
name = "QGis server"
|
name = "QGis server"
|
||||||
|
@ -1130,7 +1293,7 @@ website = "https://app.rawgraphs.io/"
|
||||||
name = "Redash"
|
name = "Redash"
|
||||||
description = "Connect to any data source, easily visualize, dashboard and share your data."
|
description = "Connect to any data source, easily visualize, dashboard and share your data."
|
||||||
upstream = "https://github.com/getredash/redash"
|
upstream = "https://github.com/getredash/redash"
|
||||||
website = ""
|
website = "https://redash.io/"
|
||||||
|
|
||||||
[renovate]
|
[renovate]
|
||||||
name = "Renovate"
|
name = "Renovate"
|
||||||
|
@ -1166,7 +1329,7 @@ website = "https://revolt.chat/"
|
||||||
name = "RSS-proxy"
|
name = "RSS-proxy"
|
||||||
description = "Create an RSS or ATOM feed of almost any website, just by analyzing just the static HTML structure."
|
description = "Create an RSS or ATOM feed of almost any website, just by analyzing just the static HTML structure."
|
||||||
upstream = "https://github.com/damoeb/rss-proxy"
|
upstream = "https://github.com/damoeb/rss-proxy"
|
||||||
website = ""
|
website = "https://rssproxy.migor.org/"
|
||||||
|
|
||||||
[sabnzbd]
|
[sabnzbd]
|
||||||
name = "SABnzbd"
|
name = "SABnzbd"
|
||||||
|
@ -1179,6 +1342,7 @@ name = "SAT"
|
||||||
description = "An all-in-one tool to manage all your communications"
|
description = "An all-in-one tool to manage all your communications"
|
||||||
upstream = ""
|
upstream = ""
|
||||||
website = "https://salut-a-toi.org"
|
website = "https://salut-a-toi.org"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/sat_ynh"
|
||||||
|
|
||||||
[screego]
|
[screego]
|
||||||
name = "Screego"
|
name = "Screego"
|
||||||
|
@ -1191,6 +1355,7 @@ name = "Scribe"
|
||||||
description = "An alternative frontend to Medium"
|
description = "An alternative frontend to Medium"
|
||||||
upstream = "https://git.sr.ht/~edwardloveall/scribe"
|
upstream = "https://git.sr.ht/~edwardloveall/scribe"
|
||||||
website = "https://scribe.rip/"
|
website = "https://scribe.rip/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/scribe_ynh"
|
||||||
|
|
||||||
[semantic-mediawiki]
|
[semantic-mediawiki]
|
||||||
name = "Semantic MediaWiki"
|
name = "Semantic MediaWiki"
|
||||||
|
@ -1202,24 +1367,26 @@ website = "https://www.semantic-mediawiki.org/wiki/Semantic_MediaWiki"
|
||||||
name = "Semaphore"
|
name = "Semaphore"
|
||||||
description = "A fediverse (Mastodon-API compatible) accessible, simple and fast web client"
|
description = "A fediverse (Mastodon-API compatible) accessible, simple and fast web client"
|
||||||
upstream = "https://github.com/NickColley/semaphore"
|
upstream = "https://github.com/NickColley/semaphore"
|
||||||
website = ""
|
website = "https://semaphore.social/"
|
||||||
|
|
||||||
[shadowsocks]
|
[shadowsocks]
|
||||||
name = "shadowsocks"
|
name = "shadowsocks"
|
||||||
description = "A SOCKS5 proxy to protect your Internet traffic"
|
description = "A SOCKS5 proxy to protect your Internet traffic"
|
||||||
upstream = ""
|
upstream = "https://github.com/shadowsocks/shadowsocks-org"
|
||||||
website = "https://shadowsocks.org"
|
website = "https://shadowsocks.org"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/shadowsocks_ynh"
|
||||||
|
|
||||||
[shinken]
|
[shinken]
|
||||||
name = "shinken"
|
name = "shinken"
|
||||||
description = "A flexible and scalable monitoring framework"
|
description = "A flexible and scalable monitoring framework"
|
||||||
upstream = "https://github.com/naparuba/shinken"
|
upstream = "https://github.com/naparuba/shinken"
|
||||||
website = ""
|
website = "http://www.shinken-monitoring.org/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/shinken_ynh"
|
||||||
|
|
||||||
[sickrage]
|
[sickchill]
|
||||||
name = "sickrage"
|
name = "sickchill"
|
||||||
description = "Automatic TV shows downloader"
|
description = "Automatic TV shows downloader"
|
||||||
upstream = ""
|
upstream = "https://github.com/SickChill/sickchill"
|
||||||
website = "https://sickchill.github.io/"
|
website = "https://sickchill.github.io/"
|
||||||
|
|
||||||
[signal-proxy]
|
[signal-proxy]
|
||||||
|
@ -1228,6 +1395,12 @@ description = "Fight censorship and bypass traffic securely to the Signal servic
|
||||||
upstream = "https://github.com/signalapp/Signal-TLS-Proxy"
|
upstream = "https://github.com/signalapp/Signal-TLS-Proxy"
|
||||||
website = "https://signal.org/blog/help-iran-reconnect/"
|
website = "https://signal.org/blog/help-iran-reconnect/"
|
||||||
|
|
||||||
|
[silverbullet]
|
||||||
|
name = "SilverBullet"
|
||||||
|
description = "Extensible personal knowledge management system with plain markdown files."
|
||||||
|
upstream = "https://github.com/silverbulletmd/silverbullet"
|
||||||
|
website = "https://silverbullet.md/"
|
||||||
|
|
||||||
[simplelogin]
|
[simplelogin]
|
||||||
name = "SimpleLogin"
|
name = "SimpleLogin"
|
||||||
description = "Privacy-first e-mail forwarding and identity provider service"
|
description = "Privacy-first e-mail forwarding and identity provider service"
|
||||||
|
@ -1250,7 +1423,8 @@ website = "https://socialhome.network"
|
||||||
name = "sphinx"
|
name = "sphinx"
|
||||||
description = "The Sphinx documentation generator"
|
description = "The Sphinx documentation generator"
|
||||||
upstream = "https://github.com/sphinx-doc/sphinx"
|
upstream = "https://github.com/sphinx-doc/sphinx"
|
||||||
website = ""
|
website = "https://www.sphinx-doc.org/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/sphinx_ynh"
|
||||||
|
|
||||||
[spodcast]
|
[spodcast]
|
||||||
name = "Spodcast"
|
name = "Spodcast"
|
||||||
|
@ -1276,6 +1450,12 @@ description = "Gallery/Camera application with private encrypted Backup and Sync
|
||||||
upstream = "https://github.com/stingle/stingle-api"
|
upstream = "https://github.com/stingle/stingle-api"
|
||||||
website = "https://stingle.org/"
|
website = "https://stingle.org/"
|
||||||
|
|
||||||
|
[stirling-pdf]
|
||||||
|
name = "Stirling PDF"
|
||||||
|
description = "Edit, compress, sign, OCR and other various operations on PDF files"
|
||||||
|
upstream = "https://github.com/Frooodle/Stirling-PDF"
|
||||||
|
website = ""
|
||||||
|
|
||||||
[storj]
|
[storj]
|
||||||
name = "Storj"
|
name = "Storj"
|
||||||
description = "Ongoing Storj v3 development. Decentralized cloud object storage that is affordable, easy to use, private, and secure."
|
description = "Ongoing Storj v3 development. Decentralized cloud object storage that is affordable, easy to use, private, and secure."
|
||||||
|
@ -1304,13 +1484,14 @@ website = "https://suitecrm.com/"
|
||||||
name = "Superalgos"
|
name = "Superalgos"
|
||||||
description = "Crypto trading bot, automated bitcoin / cryptocurrency trading software."
|
description = "Crypto trading bot, automated bitcoin / cryptocurrency trading software."
|
||||||
upstream = "https://github.com/Superalgos/Superalgos"
|
upstream = "https://github.com/Superalgos/Superalgos"
|
||||||
website = ""
|
website = "https://superalgos.org/"
|
||||||
|
|
||||||
[sympa]
|
[sympa]
|
||||||
name = "Sympa"
|
name = "Sympa"
|
||||||
description = "Mailing List manager"
|
description = "Mailing List manager"
|
||||||
upstream = ""
|
upstream = "https://github.com/sympa-community/sympa"
|
||||||
website = "https://www.sympa.org/"
|
website = "https://www.sympa.community/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/sympa_ynh"
|
||||||
|
|
||||||
[syspass]
|
[syspass]
|
||||||
name = "Syspass"
|
name = "Syspass"
|
||||||
|
@ -1326,7 +1507,7 @@ website = "https://tahoe-lafs.org/"
|
||||||
|
|
||||||
[taiga]
|
[taiga]
|
||||||
name = "Taiga"
|
name = "Taiga"
|
||||||
description = ""
|
description = "Project management"
|
||||||
upstream = "https://github.com/kaleidos-ventures/taiga-back"
|
upstream = "https://github.com/kaleidos-ventures/taiga-back"
|
||||||
website = "https://taiga.io"
|
website = "https://taiga.io"
|
||||||
|
|
||||||
|
@ -1360,6 +1541,12 @@ description = "Multi-protocol access proxy which understands SSH, HTTPS, RDP, Ku
|
||||||
upstream = "https://github.com/gravitational/teleport"
|
upstream = "https://github.com/gravitational/teleport"
|
||||||
website = "https://goteleport.com/"
|
website = "https://goteleport.com/"
|
||||||
|
|
||||||
|
[teslamate]
|
||||||
|
name = "Teslamate"
|
||||||
|
description = "A powerful, self-hosted data logger for your Tesla"
|
||||||
|
upstream = "https://github.com/adriankumpf/teslamate"
|
||||||
|
website = "https://docs.teslamate.org/docs/installation/docker"
|
||||||
|
|
||||||
[theia-ide]
|
[theia-ide]
|
||||||
name = "Theia-IDE"
|
name = "Theia-IDE"
|
||||||
description = "VS Code-like cloud IDE"
|
description = "VS Code-like cloud IDE"
|
||||||
|
@ -1384,12 +1571,6 @@ description = "Instant Terminal Sharing"
|
||||||
upstream = "https://github.com/tmate-io/tmate"
|
upstream = "https://github.com/tmate-io/tmate"
|
||||||
website = "https://tmate.io/"
|
website = "https://tmate.io/"
|
||||||
|
|
||||||
[traccar]
|
|
||||||
name = "Traccar"
|
|
||||||
description = "Modern GPS Tracking Platform"
|
|
||||||
upstream = "https://github.com/traccar/traccar"
|
|
||||||
website = ""
|
|
||||||
|
|
||||||
[trivy]
|
[trivy]
|
||||||
name = "trivy"
|
name = "trivy"
|
||||||
description = "OSS Vulnerability and Misconfiguration Scanning."
|
description = "OSS Vulnerability and Misconfiguration Scanning."
|
||||||
|
@ -1405,14 +1586,15 @@ website = "https://www.tryton.org/"
|
||||||
[tubesync]
|
[tubesync]
|
||||||
name = "tubesync"
|
name = "tubesync"
|
||||||
description = "Syncs YouTube channels and playlists to a locally hosted media server"
|
description = "Syncs YouTube channels and playlists to a locally hosted media server"
|
||||||
upstream = "https://github.com/meeb/tubesyn"
|
upstream = "https://github.com/meeb/tubesync"
|
||||||
website = ""
|
website = ""
|
||||||
|
|
||||||
[tutao]
|
[tutao]
|
||||||
name = "tutao"
|
name = "tutao"
|
||||||
description = "End-to-end encrypted e-mail client"
|
description = "End-to-end encrypted e-mail client"
|
||||||
upstream = "https://github.com/tutao/tutanota/"
|
upstream = "https://github.com/tutao/tutanota/"
|
||||||
website = ""
|
website = "https://tuta.com/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/tutao_ynh"
|
||||||
|
|
||||||
[twake-app]
|
[twake-app]
|
||||||
name = "Twake.app"
|
name = "Twake.app"
|
||||||
|
@ -1431,6 +1613,7 @@ name = "umap"
|
||||||
description = "Cartography software"
|
description = "Cartography software"
|
||||||
upstream = ""
|
upstream = ""
|
||||||
website = "https://umap.openstreetmap.fr/"
|
website = "https://umap.openstreetmap.fr/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/umap_ynh"
|
||||||
|
|
||||||
[upmpdcli]
|
[upmpdcli]
|
||||||
name = "upmpdcli"
|
name = "upmpdcli"
|
||||||
|
@ -1450,6 +1633,18 @@ description = "Build and share document collections"
|
||||||
upstream = "https://github.com/huridocs/uwazi"
|
upstream = "https://github.com/huridocs/uwazi"
|
||||||
website = "https://www.uwazi.io/"
|
website = "https://www.uwazi.io/"
|
||||||
|
|
||||||
|
[vod2podrss]
|
||||||
|
name = "Vod2PodRSS"
|
||||||
|
description = "Convert YouTube or Twitch channels RSS feed"
|
||||||
|
upstream = "https://github.com/madiele/vod2pod-rss"
|
||||||
|
website = ""
|
||||||
|
|
||||||
|
[voyantserver]
|
||||||
|
name = "VoyantServer"
|
||||||
|
description = "Runs a webUI and backend for VoyantTools, a textual concordance and analysis java app."
|
||||||
|
upstream = "https://github.com/voyanttools/VoyantServer"
|
||||||
|
website = "https://voyant-tools.org/"
|
||||||
|
|
||||||
[vpn-server]
|
[vpn-server]
|
||||||
name = "VPN server"
|
name = "VPN server"
|
||||||
description = "Create/provide VPNs from your server"
|
description = "Create/provide VPNs from your server"
|
||||||
|
@ -1467,12 +1662,13 @@ name = "webogram"
|
||||||
description = "A new era of messaging"
|
description = "A new era of messaging"
|
||||||
upstream = "https://github.com/zhukov/webogram"
|
upstream = "https://github.com/zhukov/webogram"
|
||||||
website = ""
|
website = ""
|
||||||
|
draft = "https://github.com/YunoHost-Apps/webogram_ynh"
|
||||||
|
|
||||||
[webterminal]
|
[webterminal]
|
||||||
name = "Webterminal"
|
name = "Webterminal"
|
||||||
description = "A web-based Jump Host / Bastion, supports VNC, SSH, RDP, Telnet, SFTP..."
|
description = "A web-based Jump Host / Bastion, supports VNC, SSH, RDP, Telnet, SFTP..."
|
||||||
upstream = "https://github.com/jimmy201602/webterminal/"
|
upstream = "https://github.com/jimmy201602/webterminal/"
|
||||||
website = ""
|
website = "https://jimmy201602.github.io/webterminal/"
|
||||||
|
|
||||||
[webthings-gateway]
|
[webthings-gateway]
|
||||||
name = "WebThings Gateway"
|
name = "WebThings Gateway"
|
||||||
|
@ -1508,19 +1704,26 @@ website = "https://wikisuite.org/Software"
|
||||||
name = "WildDuck"
|
name = "WildDuck"
|
||||||
description = "Opinionated email server"
|
description = "Opinionated email server"
|
||||||
upstream = "https://github.com/nodemailer/wildduck"
|
upstream = "https://github.com/nodemailer/wildduck"
|
||||||
website = ""
|
website = "https://wildduck.email/"
|
||||||
|
|
||||||
|
[windmill]
|
||||||
|
name = "Windmill"
|
||||||
|
description = "Developer platform for APIs, background jobs, workflows and UIs"
|
||||||
|
upstream = "https://github.com/windmill-labs/windmill"
|
||||||
|
website = "https://www.windmill.dev/"
|
||||||
|
|
||||||
[wisemapping]
|
[wisemapping]
|
||||||
name = "Wisemapping"
|
name = "Wisemapping"
|
||||||
description = "An online mind mapping editor"
|
description = "An online mind mapping editor"
|
||||||
upstream = "https://bitbucket.org/wisemapping/wisemapping-open-source"
|
upstream = "https://bitbucket.org/wisemapping/wisemapping-open-source"
|
||||||
website = ""
|
website = "https://www.wisemapping.com/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/wisemapping_ynh"
|
||||||
|
|
||||||
[workadventure]
|
[workadventure]
|
||||||
name = "WorkAdventure"
|
name = "WorkAdventure"
|
||||||
description = "A web-based collaborative workspace for small to medium teams"
|
description = "A web-based collaborative workspace for small to medium teams"
|
||||||
upstream = "https://github.com/thecodingmachine/workadventure"
|
upstream = "https://github.com/thecodingmachine/workadventure"
|
||||||
website = ""
|
website = "https://workadventu.re/"
|
||||||
|
|
||||||
[xbrowsersync]
|
[xbrowsersync]
|
||||||
name = "xBrowserSync"
|
name = "xBrowserSync"
|
||||||
|
@ -1532,11 +1735,11 @@ website = "https://www.xbrowsersync.org/"
|
||||||
name = "Xibo"
|
name = "Xibo"
|
||||||
description = "A FLOSS digital signage solution"
|
description = "A FLOSS digital signage solution"
|
||||||
upstream = "https://github.com/xibosignage/xibo-cms"
|
upstream = "https://github.com/xibosignage/xibo-cms"
|
||||||
website = ""
|
website = "https://xibosignage.com/cms"
|
||||||
|
|
||||||
[xonotic]
|
[xonotic]
|
||||||
name = "Xonotic"
|
name = "Xonotic"
|
||||||
description = ""
|
description = "Fast paced first person shooter"
|
||||||
upstream = "https://gitlab.com/xonotic"
|
upstream = "https://gitlab.com/xonotic"
|
||||||
website = "https://xonotic.org"
|
website = "https://xonotic.org"
|
||||||
|
|
||||||
|
@ -1557,6 +1760,7 @@ name = "Zammad"
|
||||||
description = "Helpdesk/customer support system"
|
description = "Helpdesk/customer support system"
|
||||||
upstream = "https://github.com/zammad/zammad"
|
upstream = "https://github.com/zammad/zammad"
|
||||||
website = "https://zammad.org"
|
website = "https://zammad.org"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/zammad_ynh"
|
||||||
|
|
||||||
[zigbee2mqtt-io]
|
[zigbee2mqtt-io]
|
||||||
name = "zigbee2mqtt.io"
|
name = "zigbee2mqtt.io"
|
||||||
|
@ -1574,10 +1778,17 @@ website = "https://wiki.znc.in/ZNC"
|
||||||
name = "Zoneminder"
|
name = "Zoneminder"
|
||||||
description = "Closed-circuit television software app supporting IP, USB and Analog cameras. "
|
description = "Closed-circuit television software app supporting IP, USB and Analog cameras. "
|
||||||
upstream = "https://github.com/ZoneMinder/zoneminder"
|
upstream = "https://github.com/ZoneMinder/zoneminder"
|
||||||
website = ""
|
website = "https://zoneminder.com/"
|
||||||
|
|
||||||
|
[zotero]
|
||||||
|
name = "Zotero"
|
||||||
|
description = "collect, organize, annotate, cite, and share research"
|
||||||
|
upstream = "https://github.com/foxsen/zotero-selfhost"
|
||||||
|
website = "https://www.zotero.org/"
|
||||||
|
|
||||||
[zulip]
|
[zulip]
|
||||||
name = "Zulip"
|
name = "Zulip"
|
||||||
description = "Team chat that helps teams stay productive and focused."
|
description = "Team chat that helps teams stay productive and focused."
|
||||||
upstream = "https://github.com/zulip/zulip"
|
upstream = "https://github.com/zulip/zulip"
|
||||||
website = "https://zulipchat.com/"
|
website = "https://zulipchat.com/"
|
||||||
|
draft = "https://github.com/YunoHost-Apps/zulip_ynh"
|
||||||
|
|