mirror of
https://github.com/YunoHost/apps.git
synced 2024-09-03 20:06:07 +02:00
Merge pull request #1612 from YunoHost/toml-all-the-things
TOML all the things ?
This commit is contained in:
commit
0b67b0711c
13 changed files with 4398 additions and 5740 deletions
31
.github/workflows/main.yml
vendored
31
.github/workflows/main.yml
vendored
|
@ -1,4 +1,4 @@
|
|||
name: JSON validation
|
||||
name: Catalog consistency checks
|
||||
|
||||
on: pull_request
|
||||
|
||||
|
@ -9,25 +9,16 @@ jobs:
|
|||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Check JSON validity for apps.json
|
||||
- name: Set up Python 3.11
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.11
|
||||
- name: Install toml python lib
|
||||
run: |
|
||||
cat apps.json | jq >/dev/null
|
||||
|
||||
- name: Check all working apps have consistent app id / app url
|
||||
pip3 install toml
|
||||
- name: Check TOML validity for apps.toml
|
||||
run: |
|
||||
FAULTY_APPS="false";
|
||||
for LINE in $(cat apps.json | jq -r 'to_entries[] | select ( .value.state=="working" ) | "\(.key)|\(.value.url)"')
|
||||
do
|
||||
APP=$(echo $LINE | awk -F'|' '{print $1}')
|
||||
URL_END=$(echo $LINE | awk -F'/' '{print $NF}')
|
||||
[ "$APP" == "$(echo $APP | tr [A-Z] [a-z])" ] || { FAULTY_APPS="true"; echo "$APP : app id should be lowercase" >&2; }
|
||||
[ "$URL_END" == "${APP}_ynh" ] || { FAULTY_APPS="true"; echo "$APP : the url should end with ${APP}_ynh" >&2; }
|
||||
done
|
||||
[ $FAULTY_APPS = "false" ]
|
||||
|
||||
- name: Check all working apps have a category
|
||||
python3 -c "import toml; toml.load(open('apps.toml'))"
|
||||
- name: Check all working apps have consistent app id / app url and categories
|
||||
run: |
|
||||
APPS_WITH_NO_CATEGORY=$(jq -e -r '.[] | select ( .state=="working" ) | select ( has("category") | not )' apps.json || true)
|
||||
[ "$APPS_WITH_NO_CATEGORY" == "" ] || { echo "Some working apps are missing a category: $APPS_WITH_NO_CATEGORY" >&2; false; }
|
||||
|
||||
python3 tools/catalog_linter.py
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -9,3 +9,5 @@ tools/bot-repo-cleanup/.github_token
|
|||
|
||||
tools/autopatches/login
|
||||
tools/autopatches/token
|
||||
|
||||
.github_token
|
||||
|
|
29
README.md
29
README.md
|
@ -6,7 +6,7 @@ Here you will find the repositories and versions of every apps available in Yuno
|
|||
|
||||
It is browsable here: https://yunohost.org/apps
|
||||
|
||||
The main file of the catalog is [**apps.json**](./apps.json) which contains
|
||||
The main file of the catalog is [**apps.toml**](./apps.toml) which contains
|
||||
references to the corresponding Git repositories for each application, along
|
||||
with a few metadata about them such as its category or maintenance state. This
|
||||
file regularly read by `list_builder.py` which publish the results on
|
||||
|
@ -30,28 +30,23 @@ https://app.yunohost.org/default/.
|
|||
> with keeping your app working and up to date with packaging evolutions on the long run.
|
||||
|
||||
To add your application to the catalog:
|
||||
* Fork this repository and edit the [apps.json](https://github.com/YunoHost/apps/tree/master/apps.json) file
|
||||
* Fork this repository and edit the [apps.toml](https://github.com/YunoHost/apps/tree/master/apps.toml) file
|
||||
* Add your app's ID and git information at the right alphabetical place
|
||||
* Indicate the app's functioning state: `notworking`, `inprogress`, or `working`
|
||||
* Indicate the app category, which you can pick from `categories.yml`
|
||||
* Indicate any anti-feature that your app may be subject to, see `antifeatures.yml` (or remove the `antifeatures` key if there's none)
|
||||
* Indicate the app category, which you can pick from `categories.toml`
|
||||
* Indicate any anti-feature that your app may be subject to, see `antifeatures.toml` (or remove the `antifeatures` key if there's none)
|
||||
* Indicate if your app can be thought of as an alternative to popular proprietary services (or remove the `potential_alternative_to` key if there's none)
|
||||
* *Do not* add the `level` entry by yourself. Our automatic test suite ("the CI") will handle it.
|
||||
* Create a [Pull Request](https://github.com/YunoHost/apps/pulls/)
|
||||
|
||||
App example addition:
|
||||
```json
|
||||
"your_app": {
|
||||
"antifeatures": [
|
||||
"deprecated-software"
|
||||
],
|
||||
"potential_alternative_to": [
|
||||
"YouTube"
|
||||
],
|
||||
"category": "pick_the_appropriate_category",
|
||||
"state": "working",
|
||||
"url": "https://github.com/YunoHost-Apps/your_app_ynh"
|
||||
}
|
||||
```toml
|
||||
[your_app]
|
||||
antifeatures = [ "deprecated-software" ] # Remove if no relevant antifeature applies
|
||||
potential_alternative_to = [ "YouTube" ] # Indicate if your app can be thought of as an alternative to popular proprietary services (or remove if none applies)
|
||||
category = "foobar" # Replace with the appropriate category id found in categories.toml
|
||||
state = "working"
|
||||
url = "https://github.com/YunoHost-Apps/your_app_ynh"
|
||||
```
|
||||
|
||||
> **Warning**
|
||||
|
@ -69,6 +64,6 @@ App packagers should *not* manually set their apps' level. The levels of all the
|
|||
|
||||
### Apps flagged as not-maintained
|
||||
|
||||
Applications with no recent activity and no active sign from maintainer may be flagged in `apps.json` 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!
|
||||
|
|
90
antifeatures.toml
Normal file
90
antifeatures.toml
Normal file
|
@ -0,0 +1,90 @@
|
|||
[tracking]
|
||||
icon = "user-secret"
|
||||
title.en = "Tracking"
|
||||
title.fr = "Pistage"
|
||||
description.en = "Tracks you and/or reports your activity to upstream maintainer or third parties, either without your permission or by default."
|
||||
decription.fr = "Vous piste et/ou rapporte vos activités au mainteneur source ou à des tiers, sans votre permission ou par défaut."
|
||||
|
||||
[non-free-network]
|
||||
icon = "sitemap"
|
||||
title.en = "Non-free Network Services"
|
||||
title.fr = "Services réseau non libres"
|
||||
description.en = "Promotes or depends entirely on a non-free network service."
|
||||
description.fr = "Promeut ou utilise des services réseau non libres."
|
||||
|
||||
[non-free-addons]
|
||||
icon = "puzzle-piece"
|
||||
title.en = "Non-free Addons"
|
||||
title.fr = "Extensions non libres"
|
||||
description.en = "Promotes other non-free applications or plugins."
|
||||
description.fr = "Promeut d'autres applications ou plugins non libres."
|
||||
|
||||
[non-free-dependencies]
|
||||
icon = "book"
|
||||
title.en = "Non-free dependencies"
|
||||
title.fr = "Dépendances non libres"
|
||||
description.en = "Relies on software dependencies that are not free in order to run."
|
||||
description.fr = "Dépend pour fonctionner de dépendances logicielles non libres."
|
||||
|
||||
[non-free-assets]
|
||||
icon = "file-image-o"
|
||||
title.en = "Non-free assets"
|
||||
title.fr = "Ressources non libres"
|
||||
description.en = "Contains and makes use of non-free assets. The most common case is apps using artwork - images, sounds, music, etc. - under a commercial license."
|
||||
description.fr = "Contient ou utilise des médias non libres. Le cas le plus fréquent concerne des applications utilisant des œuvres (images, sons, musiques, etc.) sous une licence commerciale."
|
||||
|
||||
[bad-security-reputation]
|
||||
icon = "bug"
|
||||
title.en = "Bad security reputation"
|
||||
title.fr = "Mauvaise réputation en matière de sécurité"
|
||||
description.en = "Has a bad security reputation, such as deprecated addons."
|
||||
description.fr = "A une mauvaise réputation en matière de sécurité, en utilisant des plugins dépréciés par exemple."
|
||||
|
||||
[deprecated-software]
|
||||
icon = "trash-o"
|
||||
title.en = "Upstream not maintained"
|
||||
title.fr = "Application non maintenue"
|
||||
description.en = "This software is not maintained anymore. Expect it to break down over time, be exposed to unfixed security breaches, etc."
|
||||
description.fr = "Ce logiciel n'est plus maintenu. Attendez-vous à ce qu'il ne fonctionne plus avec le temps, et que l'on découvre des failles de sécurité qui ne seront pas corrigées, etc."
|
||||
|
||||
[package-not-maintained]
|
||||
icon = "user-times"
|
||||
title.en = "Package not maintained"
|
||||
title.fr = "Paquet non maintenu"
|
||||
description.en = "This YunoHost package is not maintained and needs adoption."
|
||||
description.fr = "Ce package YunoHost n'est plus maintenu et doit être adopté."
|
||||
|
||||
[paid-content]
|
||||
icon = "money"
|
||||
title.en = "Paid content"
|
||||
title.fr = "Contenu payant"
|
||||
description.en = "Promotes or depends, entirely or partially, on a paid service."
|
||||
description.fr = "Promeut ou dépend, entièrement ou partiellement, d'un service payant."
|
||||
|
||||
[arbitrary-limitations]
|
||||
icon = "star-half-empty"
|
||||
title.en = "Arbitrary limitations"
|
||||
title.fr = "Limitations arbitraires"
|
||||
description.en = "Features arbitrary limitations. Please refer to the README."
|
||||
description.fr = "Contient des limitations arbitraires. Se référer au fichier README."
|
||||
|
||||
[replaced-by-another-app]
|
||||
icon = "repeat"
|
||||
title.en = "Replaced by another app"
|
||||
title.fr = "Remplacé par une autre application"
|
||||
description.en = "Was replaced by another app. Please refer to the README."
|
||||
description.fr = "A été remplacé par une autre application. Se référer au fichier README."
|
||||
|
||||
[alpha-software]
|
||||
icon = "flask"
|
||||
title.en = "Alpha software"
|
||||
title.fr = "Logiciel en version alpha"
|
||||
description.en = "Early development stage. May contain changing or unstable features, bugs, and security vulnerability."
|
||||
description.fr = "Le logiciel est au tout début de son développement. Il pourrait contenir des fonctionnalités changeantes ou instables, des bugs, et des failles de sécurité."
|
||||
|
||||
[not-totally-free]
|
||||
icon = "lock"
|
||||
title.en = "Not totally free upstream"
|
||||
title.fr = "Application sous licence libre restreinte"
|
||||
description.en = "The packaged app is under an overall free licence, but with clauses that restrict its use."
|
||||
description.fr = "L'application packagée est sous une licence globalement libre, mais avec des clauses qui pourraient restreindre son utilisation."
|
116
antifeatures.yml
116
antifeatures.yml
|
@ -1,116 +0,0 @@
|
|||
- id: tracking
|
||||
icon: user-secret
|
||||
title:
|
||||
en: "Tracking"
|
||||
fr: "Pistage"
|
||||
description:
|
||||
en: "Tracks you and/or reports your activity to upstream maintainer or third parties, either without your permission or by default."
|
||||
fr: "Vous piste et/ou rapporte vos activités au mainteneur source ou à des tiers, sans votre permission ou par défaut."
|
||||
|
||||
- id: non-free-network
|
||||
icon: sitemap
|
||||
title:
|
||||
en: "Non-free Network Services"
|
||||
fr : "Services réseau non libres"
|
||||
description:
|
||||
en: "Promotes or depends entirely on a non-free network service."
|
||||
fr: "Promeut ou utilise des services réseau non libres."
|
||||
|
||||
- id: non-free-addons
|
||||
icon: puzzle-piece
|
||||
title:
|
||||
en: "Non-free Addons"
|
||||
fr: "Extensions non libres"
|
||||
description:
|
||||
en: "Promotes other non-free applications or plugins."
|
||||
fr: "Promeut d'autres applications ou plugins non libres."
|
||||
|
||||
- id: non-free-dependencies
|
||||
icon: book
|
||||
title:
|
||||
en: "Non-free dependencies"
|
||||
fr: "Dépendances non libres"
|
||||
description:
|
||||
en: "Relies on software dependencies that are not free in order to run."
|
||||
fr: "Dépend pour fonctionner de dépendances logicielles non libres."
|
||||
|
||||
- id: non-free-assets
|
||||
icon: file-image-o
|
||||
title:
|
||||
en: "Non-free assets"
|
||||
fr: "Ressources non libres"
|
||||
description:
|
||||
en: "Contains and makes use of non-free assets. The most common case is apps using artwork - images, sounds, music, etc. - under a commercial license."
|
||||
fr: "Contient ou utilise des médias non libres. Le cas le plus fréquent concerne des applications utilisant des œuvres (images, sons, musiques, etc.) sous une licence commerciale."
|
||||
|
||||
- id: bad-security-reputation
|
||||
icon: bug
|
||||
title:
|
||||
en: "Bad security reputation"
|
||||
fr: "Mauvaise réputation en matière de sécurité"
|
||||
description:
|
||||
en: "Has a bad security reputation, such as deprecated addons."
|
||||
fr: "A une mauvaise réputation en matière de sécurité, en utilisant des plugins dépréciés par exemple."
|
||||
|
||||
- id: deprecated-software
|
||||
icon: trash-o
|
||||
title:
|
||||
en: "Upstream not maintained"
|
||||
fr: "Application non maintenue"
|
||||
description:
|
||||
en: "This software is not maintained anymore. Expect it to break down over time, be exposed to unfixed security breaches, etc."
|
||||
fr: "Ce logiciel n'est plus maintenu. Attendez-vous à ce qu'il ne fonctionne plus avec le temps, et que l'on découvre des failles de sécurité qui ne seront pas corrigées, etc."
|
||||
|
||||
- id: package-not-maintained
|
||||
icon: user-times
|
||||
title:
|
||||
en: "Package not maintained"
|
||||
fr: "Paquet non maintenu"
|
||||
description:
|
||||
en: "This YunoHost package is not maintained and needs adoption."
|
||||
fr: "Ce package YunoHost n'est plus maintenu et doit être adopté."
|
||||
|
||||
- id: paid-content
|
||||
icon: money
|
||||
title:
|
||||
en: "Paid content"
|
||||
fr: "Contenu payant"
|
||||
description:
|
||||
en: "Promotes or depends, entirely or partially, on a paid service."
|
||||
fr: "Promeut ou dépend, entièrement ou partiellement, d'un service payant."
|
||||
|
||||
- id: arbitrary-limitations
|
||||
icon: star-half-empty
|
||||
title:
|
||||
en: "Arbitrary limitations"
|
||||
fr: "Limitations arbitraires"
|
||||
description:
|
||||
en: "Features arbitrary limitations. Please refer to the README."
|
||||
fr: "Contient des limitations arbitraires. Se référer au fichier README."
|
||||
|
||||
- id: replaced-by-another-app
|
||||
icon: repeat
|
||||
title:
|
||||
en: "Replaced by another app"
|
||||
fr: "Remplacé par une autre application"
|
||||
description:
|
||||
en: "Was replaced by another app. Please refer to the README."
|
||||
fr: "A été remplacé par une autre application. Se référer au fichier README."
|
||||
|
||||
- id: alpha-software
|
||||
icon: flask
|
||||
title:
|
||||
en: "Alpha software"
|
||||
fr: "Logiciel en version alpha"
|
||||
description:
|
||||
en: "Early development stage. May contain changing or unstable features, bugs, and security vulnerability."
|
||||
fr: "Le logiciel est au tout début de son développement. Il pourrait contenir des fonctionnalités changeantes ou instables, des bugs, et des failles de sécurité."
|
||||
|
||||
- id: not-totally-free
|
||||
icon: lock
|
||||
title:
|
||||
en: "Not totally free upstream"
|
||||
fr: "Application sous licence libre restreinte"
|
||||
description:
|
||||
en: "The packaged app is under an overall free licence, but with clauses that restrict its use."
|
||||
fr: "L'application packagée est sous une licence globalement libre, mais avec des clauses qui pourraient restreindre son utilisation."
|
298
categories.toml
Normal file
298
categories.toml
Normal file
|
@ -0,0 +1,298 @@
|
|||
[synchronization]
|
||||
icon = "cloud"
|
||||
title.en = "Synchronization"
|
||||
title.es = "Sincronización"
|
||||
title.fr = "Synchronisation"
|
||||
description.en = "Files sync, contact, calendar, password managers..."
|
||||
description.es = "Sincronización, contactos, calendario, gestor de contraseñas..."
|
||||
description.fr = "Fichiers, contacts, calendrier, mots de passe..."
|
||||
|
||||
[synchronization.subtags.files]
|
||||
title.en = "Files"
|
||||
title.es = "Archivos"
|
||||
title.fr = "Fichiers"
|
||||
|
||||
[synchronization.subtags.calendar]
|
||||
title.en = "Calendar"
|
||||
title.es = "Calendario"
|
||||
title.fr = "Calendrier"
|
||||
|
||||
[synchronization.subtags.contacts]
|
||||
title.en = "Contacts"
|
||||
title.es = "Contactos"
|
||||
title.fr = "Contacts"
|
||||
|
||||
[synchronization.subtags.password]
|
||||
title.en = "Passwords"
|
||||
title.es = "Contraseñas"
|
||||
title.fr = "Mots de passe"
|
||||
|
||||
[publishing]
|
||||
icon = "globe"
|
||||
title.en = "Publishing"
|
||||
title.es = "Publicaciones"
|
||||
title.fr = "Publication"
|
||||
description.en = "Websites, blog, wiki, CMS..."
|
||||
description.es = "Paginas Web, blog, wiki, CMS..."
|
||||
description.fr = "Site web, blog, wiki, CMS..."
|
||||
|
||||
[publishing.subtags.websites]
|
||||
title.en = "Websites"
|
||||
title.es = "Paginas web"
|
||||
title.fr = "Sites web"
|
||||
|
||||
[publishing.subtags.blog]
|
||||
title.en = "Blog"
|
||||
title.es = "blog"
|
||||
title.fr = "Blog"
|
||||
|
||||
[publishing.subtags.wiki]
|
||||
title.en = "Wiki"
|
||||
title.es = "Wiki"
|
||||
title.fr = "Wiki"
|
||||
|
||||
[publishing.subtags.ecommerce]
|
||||
title.en = "E-commerce"
|
||||
title.es = "Comercio eletronico"
|
||||
title.fr = "Vente en ligne"
|
||||
|
||||
[publishing.subtags.analytics]
|
||||
title.en = "Analytics"
|
||||
title.es = "Estadisticas"
|
||||
title.fr = "Statistiques"
|
||||
|
||||
[communication]
|
||||
icon = "comments-o"
|
||||
title.en = "Communication"
|
||||
title.es = "Comunicacion"
|
||||
title.fr = "Communication"
|
||||
description.en = "Chat, email, forum, meetings..."
|
||||
description.es = "Chat, email, foro, reuniones en grupo..."
|
||||
description.fr = "Chat, email, forum, meetings..."
|
||||
|
||||
[communication.subtags.chat]
|
||||
title.en = "Instant messaging"
|
||||
title.es = "Mensajeria Instantanea"
|
||||
title.fr = "Messagerie instantannée"
|
||||
|
||||
[communication.subtags.forum]
|
||||
title.en = "Forum"
|
||||
title.es = "Foro"
|
||||
title.fr = "Forum"
|
||||
|
||||
[communication.subtags.email]
|
||||
title.en = "Email"
|
||||
title.es = "Email"
|
||||
title.fr = "Email"
|
||||
|
||||
[communication.subtags.meeting]
|
||||
title.en = "Meetings"
|
||||
title.es = "Reuniones"
|
||||
title.fr = "Meetings"
|
||||
|
||||
[office]
|
||||
icon = "file-text-o"
|
||||
title.en = "Office"
|
||||
title.es = "Ofimatica"
|
||||
title.fr = "Bureautique"
|
||||
description.en = "Collaborative text edition, spreadsheets..."
|
||||
description.es = "Edición de texto colaborativo, hojas de cálculo..."
|
||||
description.fr = "Édition de texte collaborative, tableurs..."
|
||||
|
||||
[office.subtags.text]
|
||||
title.en = "Text"
|
||||
title.es = "Texto"
|
||||
title.fr = "Texte"
|
||||
|
||||
[office.subtags.speadsheet]
|
||||
title.en = "Speadsheet"
|
||||
title.es = "Hoja de cálculo"
|
||||
title.fr = "Tableur"
|
||||
|
||||
[office.subtags.impress]
|
||||
title.en = "Slide show"
|
||||
title.es = "Diapositivas"
|
||||
title.fr = "Diaporama"
|
||||
|
||||
[office.subtags.draw]
|
||||
title.en = "Graphism"
|
||||
title.es = "Graficos"
|
||||
title.fr = "Graphisme"
|
||||
|
||||
[office.subtags.mindmap]
|
||||
title.en = "Mindmap"
|
||||
title.fr = "Cartes mentale"
|
||||
|
||||
[productivity_and_management]
|
||||
icon = "area-chart"
|
||||
title.en = "Productivity & management"
|
||||
title.fr = "Productivité & gestion"
|
||||
description.en = "Tasks, polls, accounting, ERP..."
|
||||
description.fr = "Tâches, sondages, comptabilité, ERP..."
|
||||
|
||||
[productivity_and_management.subtags.task]
|
||||
title.en = "Task"
|
||||
title.fr = "Tâches"
|
||||
|
||||
[productivity_and_management.subtags.poll]
|
||||
title.en = "Poll"
|
||||
title.fr = "Sondage"
|
||||
|
||||
[productivity_and_management.subtags.accounting]
|
||||
title.en = "Accounting"
|
||||
title.fr = "Comptabilité"
|
||||
|
||||
[productivity_and_management.subtags.business_and_ngos]
|
||||
title.en = "Business and NGOs"
|
||||
title.fr = "Entreprises et associations"
|
||||
|
||||
[small_utilities]
|
||||
icon = "umbrella"
|
||||
title.en = "Small utilities"
|
||||
title.fr = "Petits utilitaires"
|
||||
description.en = "Pastebins, URL shortener, proxies..."
|
||||
description.fr = "Pastebins, raccourcisseurs d'URL, proxys..."
|
||||
|
||||
[small_utilities.subtags.pastebin]
|
||||
title.en = "Pastebin"
|
||||
title.fr = "Pastebin"
|
||||
|
||||
[small_utilities.subtags.url_shortener]
|
||||
title.en = "URL shortener"
|
||||
title.fr = "Raccourcisseurs d'URL"
|
||||
|
||||
[small_utilities.subtags.proxy]
|
||||
title.en = "Proxy"
|
||||
title.fr = "Proxy (Intermédiaire)"
|
||||
|
||||
[reading]
|
||||
icon = "newspaper-o"
|
||||
title.en = "Reading"
|
||||
title.fr = "Lecture"
|
||||
description.en = "Newsfeed readers, books library..."
|
||||
description.fr = "Fils d'actualité, livres..."
|
||||
|
||||
[reading.subtags.rssreader]
|
||||
title.en = "RSS readers"
|
||||
title.fr = "Lecteurs RSS"
|
||||
|
||||
[reading.subtags.books]
|
||||
title.en = "Books"
|
||||
title.fr = "Livres"
|
||||
|
||||
[multimedia]
|
||||
icon = "music"
|
||||
title.en = "Multimedia"
|
||||
title.fr = "Multimédia"
|
||||
description.en = "Music library, pictures gallery, P2P, TV shows..."
|
||||
description.fr = "Bibliothèque de musique, d'images, P2P, séries..."
|
||||
|
||||
[multimedia.subtags.mediacenter]
|
||||
title.en = "Media center"
|
||||
title.fr = "Centre multimédia"
|
||||
|
||||
[multimedia.subtags.download]
|
||||
title.en = "Download"
|
||||
title.fr = "Téléchargement"
|
||||
|
||||
[multimedia.subtags.music]
|
||||
title.en = "Music"
|
||||
title.fr = "Musique"
|
||||
|
||||
[multimedia.subtags.pictures]
|
||||
title.en = "Pictures"
|
||||
title.fr = "Images"
|
||||
|
||||
[social_media]
|
||||
icon = "users"
|
||||
title.en = "Social media"
|
||||
title.fr = "Médias sociaux"
|
||||
description.en = "Microblogging, federated media"
|
||||
description.fr = "Microblogging, médias fédérés"
|
||||
|
||||
[social_media.subtags.microblogging]
|
||||
title.en = "Microblogging"
|
||||
title.fr = "Microblogging"
|
||||
|
||||
[social_media.subtags.blogging]
|
||||
title.en = "Blogging"
|
||||
title.fr = "Blogging"
|
||||
|
||||
[social_media.subtags.events]
|
||||
title.en = "Events"
|
||||
title.fr = "Événements"
|
||||
|
||||
[social_media.subtags.videos]
|
||||
title.en = "Videos"
|
||||
title.fr = "Vidéos"
|
||||
|
||||
[social_media.subtags.pictures]
|
||||
title.en = "Pictures"
|
||||
title.fr = "Images"
|
||||
|
||||
[social_media.subtags.music]
|
||||
title.en = "Music"
|
||||
title.fr = "Musique"
|
||||
|
||||
[games]
|
||||
icon = "gamepad"
|
||||
title.en = "Games"
|
||||
title.fr = "Jeux"
|
||||
description.en = "Wanna have some fun? ;)"
|
||||
description.fr = "Envie de s'amuser ? ;)"
|
||||
|
||||
[dev]
|
||||
icon = "flask"
|
||||
title.en = "Development"
|
||||
title.fr = "Développement"
|
||||
description.en = "Git forges, apps skeleton, CI, translation..."
|
||||
description.fr = "Forges Git, squelette d'apps, CI, traduction..."
|
||||
|
||||
[dev.subtags.forge]
|
||||
title.en = "Forge"
|
||||
title.fr = "Forge"
|
||||
|
||||
[dev.subtags.skeleton]
|
||||
title.en = "Skeleton"
|
||||
title.fr = "Squelettes"
|
||||
|
||||
[dev.subtags.programming]
|
||||
title.en = "Programming"
|
||||
title.fr = "Programmation"
|
||||
|
||||
[system_tools]
|
||||
icon = "wrench"
|
||||
title.en = "System tools"
|
||||
title.fr = "Outils système"
|
||||
description.en = "Monitoring, backup, network, DB tools..."
|
||||
description.fr = "Monitoring, sauvegardes, outils réseau, bases de données..."
|
||||
|
||||
[system_tools.subtags.backup]
|
||||
title.en = "Backup"
|
||||
title.fr = "Sauvegardes"
|
||||
|
||||
[system_tools.subtags.monitoring]
|
||||
title.en = "Monitoring"
|
||||
title.fr = "Monitoring"
|
||||
|
||||
[system_tools.subtags.network]
|
||||
title.en = "Network"
|
||||
title.fr = "Réseau"
|
||||
|
||||
[system_tools.subtags.db]
|
||||
title.en = "Databases"
|
||||
title.fr = "Bases de données"
|
||||
|
||||
[iot]
|
||||
icon = "home"
|
||||
title.en = "Internet of Things (IoT)"
|
||||
title.fr = "Internet des objets (IoT)"
|
||||
description.en = "Home automation, energy dashboard..."
|
||||
description.fr = "Domotique, énergie..."
|
||||
|
||||
[wat]
|
||||
icon = "tree"
|
||||
title.en = "Wat"
|
||||
title.fr = "Wat"
|
||||
description.en = "Weird experimental or very-custom stuff"
|
||||
description.fr = "Trucs expérimentaux et autres projets spécifiques"
|
324
categories.yml
324
categories.yml
|
@ -1,324 +0,0 @@
|
|||
- id: "synchronization"
|
||||
icon: "cloud"
|
||||
title:
|
||||
en: "Synchronization"
|
||||
es: "Sincronización"
|
||||
fr: "Synchronisation"
|
||||
description:
|
||||
en: "Files sync, contact, calendar, password managers..."
|
||||
es: "Sincronización, contactos, calendario, gestor de contraseñas..."
|
||||
fr: "Fichiers, contacts, calendrier, mots de passe..."
|
||||
subtags:
|
||||
- id: files
|
||||
title:
|
||||
en: Files
|
||||
es: Archivos
|
||||
fr: Fichiers
|
||||
- id: calendar
|
||||
title:
|
||||
en: Calendar
|
||||
es: Calendario
|
||||
fr: Calendrier
|
||||
- id: contacts
|
||||
title:
|
||||
en: Contacts
|
||||
es: Contactos
|
||||
fr: Contacts
|
||||
- id: password
|
||||
title:
|
||||
en: Passwords
|
||||
es: Contraseñas
|
||||
fr: Mots de passe
|
||||
- id: "publishing"
|
||||
icon: "globe"
|
||||
title:
|
||||
en: "Publishing"
|
||||
es: "Publicaciones"
|
||||
fr: "Publication"
|
||||
description:
|
||||
en: "Websites, blog, wiki, CMS..."
|
||||
es: "Paginas Web, blog, wiki, CMS..."
|
||||
fr: "Site web, blog, wiki, CMS..."
|
||||
subtags:
|
||||
- id: websites
|
||||
title:
|
||||
en: Websites
|
||||
es: Paginas web
|
||||
fr: Sites web
|
||||
- id: blog
|
||||
title:
|
||||
en: Blog
|
||||
es: blog
|
||||
fr: Blog
|
||||
- id: wiki
|
||||
title:
|
||||
en: Wiki
|
||||
es: Wiki
|
||||
fr: Wiki
|
||||
- id: ecommerce
|
||||
title:
|
||||
en: E-commerce
|
||||
es: Comercio eletronico
|
||||
fr: Vente en ligne
|
||||
- id: analytics
|
||||
title:
|
||||
en: Analytics
|
||||
es: Estadisticas
|
||||
fr: Statistiques
|
||||
- id: "communication"
|
||||
icon: "comments-o"
|
||||
title:
|
||||
en: "Communication"
|
||||
es: "Comunicacion"
|
||||
fr: "Communication"
|
||||
description:
|
||||
en: "Chat, email, forum, meetings..."
|
||||
es: "Chat, email, foro, reuniones en grupo..."
|
||||
fr: "Chat, email, forum, meetings..."
|
||||
subtags:
|
||||
- id: chat
|
||||
title:
|
||||
en: Instant messaging
|
||||
es: Mensajeria Instantanea
|
||||
fr: Messagerie instantannée
|
||||
- id: forum
|
||||
title:
|
||||
en: Forum
|
||||
es: Foro
|
||||
fr: Forum
|
||||
- id: email
|
||||
title:
|
||||
en: Email
|
||||
es: Email
|
||||
fr: Email
|
||||
- id: meeting
|
||||
title:
|
||||
en: Meetings
|
||||
es: Reuniones
|
||||
fr: Meetings
|
||||
- id: "office"
|
||||
icon: "file-text-o"
|
||||
title:
|
||||
en: "Office"
|
||||
es: "Ofimatica"
|
||||
fr: "Bureautique"
|
||||
description:
|
||||
en: "Collaborative text edition, spreadsheets..."
|
||||
es: "Edición de texto colaborativo, hojas de cálculo..."
|
||||
fr: "Édition de texte collaborative, tableurs..."
|
||||
subtags:
|
||||
- id: text
|
||||
title:
|
||||
en: Text
|
||||
es: Texto
|
||||
fr: Texte
|
||||
- id: spreadsheet
|
||||
title:
|
||||
en: Speadsheet
|
||||
es: Hoja de cálculo
|
||||
fr: Tableur
|
||||
- id: impress
|
||||
title:
|
||||
en: Slide show
|
||||
es: Diapositivas
|
||||
fr: Diaporama
|
||||
- id: draw
|
||||
title:
|
||||
en: Graphism
|
||||
es: Graficos
|
||||
fr: Graphisme
|
||||
- id: mindmap
|
||||
title:
|
||||
en: Mindmap
|
||||
fr: Cartes mentale
|
||||
- id: "productivity_and_management"
|
||||
icon: "area-chart"
|
||||
title:
|
||||
en: "Productivity & management"
|
||||
fr: "Productivité & gestion"
|
||||
description:
|
||||
en: "Tasks, polls, accounting, ERP..."
|
||||
fr: "Tâches, sondages, comptabilité, ERP..."
|
||||
subtags:
|
||||
- id: task
|
||||
title:
|
||||
en: Task
|
||||
fr: Tâches
|
||||
- id: poll
|
||||
title:
|
||||
en: Poll
|
||||
fr: Sondage
|
||||
- id: accounting
|
||||
title:
|
||||
en: Accounting
|
||||
fr: Comptabilité
|
||||
- id: business_and_ngos
|
||||
title:
|
||||
en: Business and NGOs
|
||||
fr: Entreprises et associations
|
||||
- id: "small_utilities"
|
||||
icon: "umbrella"
|
||||
title:
|
||||
en: "Small utilities"
|
||||
fr: "Petits utilitaires"
|
||||
description:
|
||||
en: "Pastebins, URL shortener, proxies..."
|
||||
fr: "Pastebins, raccourcisseurs d'URL, proxys..."
|
||||
subtags:
|
||||
- id: pastebin
|
||||
title:
|
||||
en: Pastebin
|
||||
fr: Pastebin
|
||||
- id: url_shortener
|
||||
title:
|
||||
en: "URL shortener"
|
||||
fr: "Raccourcisseurs d'URL"
|
||||
- id: proxy
|
||||
title:
|
||||
en: "Proxy"
|
||||
fr: "Proxy (Intermédiaire)"
|
||||
- id: "reading"
|
||||
icon: "newspaper-o"
|
||||
title:
|
||||
en: "Reading"
|
||||
fr: "Lecture"
|
||||
description:
|
||||
en: "Newsfeed readers, books library..."
|
||||
fr: "Fils d'actualité, livres..."
|
||||
subtags:
|
||||
- id: rssreader
|
||||
title:
|
||||
en: RSS readers
|
||||
fr: Lecteurs RSS
|
||||
- id: books
|
||||
title:
|
||||
en: Books
|
||||
fr: Livres
|
||||
- id: "multimedia"
|
||||
icon: "music"
|
||||
title:
|
||||
en: "Multimedia"
|
||||
fr: "Multimédia"
|
||||
description:
|
||||
en: "Music library, pictures gallery, P2P, TV shows..."
|
||||
fr: "Bibliothèque de musique, d'images, P2P, séries..."
|
||||
subtags:
|
||||
- id: mediacenter
|
||||
title:
|
||||
en: Media center
|
||||
fr: Centre multimédia
|
||||
- id: download
|
||||
title:
|
||||
en: Download
|
||||
fr: Téléchargement
|
||||
- id: music
|
||||
title:
|
||||
en: Music
|
||||
fr: Musique
|
||||
- id: pictures
|
||||
title:
|
||||
en: Pictures
|
||||
fr: Images
|
||||
- id: "social_media"
|
||||
icon: "users"
|
||||
title:
|
||||
en: "Social media"
|
||||
fr: "Médias sociaux"
|
||||
description:
|
||||
en: "Microblogging, federated media"
|
||||
fr: "Microblogging, médias fédérés"
|
||||
subtags:
|
||||
- id: microblogging
|
||||
title:
|
||||
en: Microblogging
|
||||
fr: Microblogging
|
||||
- id: blogging
|
||||
title:
|
||||
en: Blogging
|
||||
fr: Blogging
|
||||
- id: events
|
||||
title:
|
||||
en: Events
|
||||
fr: Événements
|
||||
- id: videos
|
||||
title:
|
||||
en: Videos
|
||||
fr: Vidéos
|
||||
- id: pictures
|
||||
title:
|
||||
en: Pictures
|
||||
fr: Images
|
||||
- id: music
|
||||
title:
|
||||
en: Music
|
||||
fr: Musique
|
||||
- id: "games"
|
||||
icon: "gamepad"
|
||||
title:
|
||||
en: "Games"
|
||||
fr: "Jeux"
|
||||
description:
|
||||
en: "Wanna have some fun? ;)"
|
||||
fr: "Envie de s'amuser ? ;)"
|
||||
- id: "dev"
|
||||
icon: "flask"
|
||||
title:
|
||||
en: "Development"
|
||||
fr: "Développement"
|
||||
description:
|
||||
en: "Git forges, apps skeleton, CI, translation..."
|
||||
fr: "Forges Git, squelette d'apps, CI, traduction..."
|
||||
subtags:
|
||||
- id: forge
|
||||
title:
|
||||
en: Forge
|
||||
fr: Forge
|
||||
- id: skeleton
|
||||
title:
|
||||
en: Skeleton
|
||||
fr: Squelettes
|
||||
- id: programming
|
||||
title:
|
||||
en: Programming
|
||||
fr: Programmation
|
||||
- id: "system_tools"
|
||||
icon: "wrench"
|
||||
title:
|
||||
en: "System tools"
|
||||
fr: "Outils système"
|
||||
description:
|
||||
en: "Monitoring, backup, network, DB tools..."
|
||||
fr: "Monitoring, sauvegardes, outils réseau, bases de données..."
|
||||
subtags:
|
||||
- id: backup
|
||||
title:
|
||||
en: Backup
|
||||
fr: Sauvegardes
|
||||
- id: monitoring
|
||||
title:
|
||||
en: Monitoring
|
||||
fr: Monitoring
|
||||
- id: network
|
||||
title:
|
||||
en: Network
|
||||
fr: Réseau
|
||||
- id: db
|
||||
title:
|
||||
en: Databases
|
||||
fr: Bases de données
|
||||
- id: "iot"
|
||||
icon: "home"
|
||||
title:
|
||||
en: "Internet of Things (IoT)"
|
||||
fr: "Internet des objets (IoT)"
|
||||
description:
|
||||
en: "Home automation, energy dashboard..."
|
||||
fr: "Domotique, énergie..."
|
||||
- id: "wat"
|
||||
icon: "tree"
|
||||
title:
|
||||
en: "Wat"
|
||||
fr: "Wat"
|
||||
description:
|
||||
en: "Weird experimental or very-custom stuff"
|
||||
fr: "Trucs expérimentaux et autres projets spécifiques"
|
|
@ -7,7 +7,6 @@ import re
|
|||
import json
|
||||
import toml
|
||||
import subprocess
|
||||
import yaml
|
||||
import time
|
||||
|
||||
from collections import OrderedDict
|
||||
|
@ -15,7 +14,20 @@ from tools.packaging_v2.convert_v1_manifest_to_v2_for_catalog import convert_v1_
|
|||
|
||||
now = time.time()
|
||||
|
||||
catalog = json.load(open("apps.json"))
|
||||
# Load categories and reformat the structure to have a list with an "id" key
|
||||
categories = toml.load(open("categories.toml"))
|
||||
for category_id, infos in categories.items():
|
||||
infos["id"] = category_id
|
||||
categories = list(categories.values())
|
||||
|
||||
# (Same for antifeatures)
|
||||
antifeatures = toml.load(open("antifeatures.toml"))
|
||||
for antifeature_id, infos in antifeatures.items():
|
||||
infos["id"] = antifeature_id
|
||||
antifeatures = list(antifeatures.values())
|
||||
|
||||
# Load the app catalog and filter out the non-working ones
|
||||
catalog = toml.load(open("apps.toml"))
|
||||
catalog = {
|
||||
app: infos for app, infos in catalog.items() if infos.get("state") != "notworking"
|
||||
}
|
||||
|
@ -181,8 +193,6 @@ def build_catalog():
|
|||
result_dict_with_manifest_v1 = copy.deepcopy(result_dict)
|
||||
result_dict_with_manifest_v1 = {name: infos for name, infos in result_dict_with_manifest_v1.items() if float(str(infos["manifest"].get("packaging_format", "")).strip() or "0") < 2}
|
||||
|
||||
categories = yaml.load(open("categories.yml").read())
|
||||
antifeatures = yaml.load(open("antifeatures.yml").read())
|
||||
os.system("mkdir -p ./builds/default/v2/")
|
||||
with open("builds/default/v2/apps.json", "w") as f:
|
||||
f.write(
|
||||
|
@ -239,7 +249,6 @@ def build_catalog():
|
|||
##############################
|
||||
# Version for catalog in doc #
|
||||
##############################
|
||||
categories = yaml.load(open("categories.yml").read())
|
||||
os.system("mkdir -p ./builds/default/doc_catalog")
|
||||
|
||||
def infos_for_doc_catalog(infos):
|
||||
|
|
|
@ -4,7 +4,6 @@ import argparse
|
|||
import json
|
||||
import toml
|
||||
import os
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
@ -33,11 +32,10 @@ def generate_READMEs(app_path: str):
|
|||
|
||||
upstream = manifest.get("upstream", {})
|
||||
|
||||
catalog = json.load(open(Path(os.path.abspath(__file__)).parent.parent.parent / "apps.json"))
|
||||
catalog = toml.load(open(Path(os.path.abspath(__file__)).parent.parent.parent / "apps.toml"))
|
||||
from_catalog = catalog.get(manifest['id'], {})
|
||||
|
||||
antifeatures_list = yaml.load(open(Path(os.path.abspath(__file__)).parent.parent.parent / "antifeatures.yml"), Loader=yaml.SafeLoader)
|
||||
antifeatures_list = { e['id']: e for e in antifeatures_list }
|
||||
antifeatures_list = toml.load(open(Path(os.path.abspath(__file__)).parent.parent.parent / "antifeatures.toml"))
|
||||
|
||||
if not upstream and not (app_path / "doc" / "DISCLAIMER.md").exists():
|
||||
print(
|
||||
|
|
28
tools/catalog_linter.py
Normal file
28
tools/catalog_linter.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
import toml
|
||||
import sys
|
||||
|
||||
catalog = toml.load(open('apps.toml'))
|
||||
catalog = {app: infos for app, infos in catalog.items() if infos.get('state') == "working"}
|
||||
categories = toml.load(open('categories.toml')).keys()
|
||||
|
||||
def check_apps():
|
||||
|
||||
for app, infos in catalog.items():
|
||||
|
||||
repo_name = infos.get("url", "").split("/")[-1]
|
||||
if repo_name != app + "_ynh":
|
||||
yield f"{app}: repo name should be {app}_ynh, not in {repo_name}"
|
||||
|
||||
category = infos.get("category")
|
||||
if not category:
|
||||
yield f"{app}: missing category"
|
||||
if category not in categories:
|
||||
yield f"{app}: category {category} is not defined in categories.toml"
|
||||
|
||||
errors = list(check_apps())
|
||||
|
||||
for error in errors:
|
||||
print(error)
|
||||
|
||||
if errors:
|
||||
sys.exit(1)
|
106
tools/update_app_levels/update_app_levels.py
Normal file
106
tools/update_app_levels/update_app_levels.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
import time
|
||||
import toml
|
||||
import requests
|
||||
import tempfile
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
|
||||
token = open(".github_token").read().strip()
|
||||
|
||||
tmpdir = tempfile.mkdtemp(prefix="update_app_levels_")
|
||||
os.system(f"git clone 'https://oauth2:{token}@github.com/yunohost/apps' {tmpdir}")
|
||||
os.system(f"git -C {tmpdir} checkout -b update_app_levels")
|
||||
|
||||
# Load the app catalog and filter out the non-working ones
|
||||
catalog = toml.load(open(f"{tmpdir}/apps.toml"))
|
||||
|
||||
# Fetch results from the CI
|
||||
CI_RESULTS_URL = "https://ci-apps.yunohost.org/ci/logs/list_level_stable_amd64.json"
|
||||
ci_results = requests.get(CI_RESULTS_URL).json()
|
||||
|
||||
comment = {
|
||||
"major_regressions": [],
|
||||
"minor_regressions": [],
|
||||
"improvements": [],
|
||||
"outdated": [],
|
||||
"missing": [],
|
||||
}
|
||||
|
||||
for app, infos in catalog.items():
|
||||
|
||||
if infos.get("state") != "working":
|
||||
continue
|
||||
|
||||
if app not in ci_results:
|
||||
comment["missing"].append(app)
|
||||
continue
|
||||
|
||||
# 3600 * 24 * 60 = ~2 months
|
||||
if (int(time.time()) - ci_results[app].get("timestamp", 0)) > 3600 * 24 * 60:
|
||||
comment["outdated"].append(app)
|
||||
continue
|
||||
|
||||
ci_level = ci_results[app]["level"]
|
||||
current_level = infos.get("level")
|
||||
|
||||
if ci_level == current_level:
|
||||
continue
|
||||
elif current_level is None or ci_level > current_level:
|
||||
comment["improvements"].append((app, current_level, ci_level))
|
||||
elif ci_level < current_level:
|
||||
if ci_level < 4 and current_level >= 4:
|
||||
comment["major_regressions"].append((app, current_level, ci_level))
|
||||
else:
|
||||
comment["minor_regressions"].append((app, current_level, ci_level))
|
||||
|
||||
infos["level"] = ci_level
|
||||
|
||||
# Also re-sort the catalog keys / subkeys
|
||||
for app, infos in catalog.items():
|
||||
catalog[app] = OrderedDict(sorted(infos.items()))
|
||||
catalog = OrderedDict(sorted(catalog.items()))
|
||||
|
||||
updated_catalog = toml.dumps(catalog)
|
||||
updated_catalog = updated_catalog.replace(",]", " ]")
|
||||
open(f"{tmpdir}/apps.toml", "w").write(updated_catalog)
|
||||
|
||||
os.system(f"git -C {tmpdir} commit apps.toml -m 'Update app levels according to CI results'")
|
||||
os.system(f"git -C {tmpdir} push origin update_app_levels --force")
|
||||
os.system(f"rm -rf {tmpdir}")
|
||||
|
||||
PR_body = ""
|
||||
if comment["major_regressions"]:
|
||||
PR_body += "\n### Major regressions\n\n"
|
||||
for app, current_level, new_level in comment['major_regressions']:
|
||||
PR_body += f"- [ ] {app} | {current_level} -> {new_level} | https://ci-apps.yunohost.org/ci/apps/{app}/latestjob\n"
|
||||
if comment["minor_regressions"]:
|
||||
PR_body += "\n### Minor regressions\n\n"
|
||||
for app, current_level, new_level in comment['minor_regressions']:
|
||||
PR_body += f"- [ ] {app} | {current_level} -> {new_level} | https://ci-apps.yunohost.org/ci/apps/{app}/latestjob\n"
|
||||
if comment["improvements"]:
|
||||
PR_body += "\n### Improvements\n\n"
|
||||
for app, current_level, new_level in comment['improvements']:
|
||||
PR_body += f"- {app} | {current_level} -> {new_level} | https://ci-apps.yunohost.org/ci/apps/{app}/latestjob\n"
|
||||
if comment["missing"]:
|
||||
PR_body += "\n### Missing results\n\n"
|
||||
for app in comment['missing']:
|
||||
PR_body += f"- {app} | https://ci-apps.yunohost.org/ci/apps/{app}/latestjob\n"
|
||||
if comment["outdated"]:
|
||||
PR_body += "\n### Outdated results\n\n"
|
||||
for app in comment['outdated']:
|
||||
PR_body += f"- [ ] {app} | https://ci-apps.yunohost.org/ci/apps/{app}/latestjob\n"
|
||||
|
||||
PR = {"title": "Update app levels accoring to CI results",
|
||||
"body": PR_body,
|
||||
"head": "update_app_levels",
|
||||
"base": "master"}
|
||||
|
||||
with requests.Session() as s:
|
||||
s.headers.update({"Authorization": f"token {token}"})
|
||||
r = s.post("https://api.github.com/repos/yunohost/apps/pulls", json.dumps(PR))
|
||||
|
||||
if r.status_code != 200:
|
||||
print(r.text)
|
||||
sys.exit(1)
|
Loading…
Add table
Reference in a new issue