Browse Source

Intégration du feu plugin gitea_maintenance

master
Eric Lupinacci 1 year ago
parent
commit
c1808e5d64
  1. 50
      ezcache/contrib.php
  2. 122
      ezcheck/controles/gitea_controle.php
  3. 50
      ezcheck/controles/gitea_orga_repos.yaml
  4. 14
      ezcheck/controles/gitea_user_recent.html
  5. 50
      ezcheck/controles/gitea_user_recent.yaml
  6. 6
      ezcheck/dashboards/contrib.yaml
  7. 13
      lang/contrib_fr.php
  8. 53
      prive/squelettes/liste/users.html
  9. 83
      services/gitea.php

50
ezcache/contrib.php vendored

@ -0,0 +1,50 @@
<?php
/**
* Ce fichier contient les fonctions de service nécessité par le plugin Check Factory.
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* Renvoie la configuration spécifique des caches de Gitea maintenance.
*
* @param string $plugin Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
* un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
*
* @return array Tableau de la configuration brute du plugin.
*/
function contrib_cache_configurer($plugin) {
// Initialisation du tableau de configuration avec les valeurs par défaut du plugin Check Factory.
$configuration = array(
'repo' => array(
'racine' => '_DIR_VAR',
'sous_dossier' => false,
'nom_prefixe' => 'repo',
'nom_obligatoire' => array('organisation'),
'nom_facultatif' => array(),
'extension' => '.txt',
'securisation' => false,
'serialisation' => false,
'decodage' => false,
'separateur' => '_',
'conservation' => 0
),
'user' => array(
'racine' => '_DIR_VAR',
'sous_dossier' => false,
'nom_prefixe' => 'user',
'nom_obligatoire' => array('liste'),
'nom_facultatif' => array(),
'extension' => '.json',
'securisation' => false,
'serialisation' => false,
'decodage' => true,
'separateur' => '_',
'conservation' => 0
),
);
return $configuration;
}

122
ezcheck/controles/gitea_controle.php

@ -0,0 +1,122 @@
<?php
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
/**
* @param int $id_controle
* @param int $id_auteur
* @param array $options
*
* @return mixed|string
*/
function gitea_orga_repos($id_controle, $id_auteur, $options) {
// Initialisation de l'erreur à chaine vide soit 'aucune erreur'.
$erreur = '';
// Récupération de la liste des organisations
// -- construction de l'url de la requête de récupération des organisations
$parametres = array(
'admin',
'orgs'
);
include_spip('services/gitea');
$url = gitea_construire_url($parametres);
// -- requête, gestion des erreurs et traitement des organisations
$reponse = gitea_requeter($url);
if (!empty($reponse['erreur'])) {
$erreur = $reponse['erreur'];
} else {
include_spip('inc/flock');
$orgas = $reponse['donnees'];
foreach ($orgas as $_orga) {
// Récupération des repos d'une organisation
$parametres = array(
'orgs',
$_orga['username'],
'repos'
);
$url = gitea_construire_url($parametres);
$reponse = gitea_requeter($url);
if (!empty($reponse['erreur'])) {
$erreur = $reponse['erreur'];
break;
} else {
// Extraction des repos et classement dans l'ordre alphabétique
$repos = $reponse['donnees'];
$repos = array_column($repos, null, 'name');
ksort($repos);
$contenu = '';
foreach ($repos as $_repo) {
$contenu .= $_repo['full_name'] . "\n";
}
// Création du fichier des repos de l'organisation
// -- Initialisation de l'identifiant du cache
$cache = array(
'organisation' => $_orga['username']
);
// -- Ecriture du cache
include_spip('inc/ezcache_cache');
cache_ecrire('contrib', 'repo', $cache, $contenu);
}
}
}
return $erreur;
}
/**
* @param int $id_controle
* @param int $id_auteur
* @param array $options
*
* @return mixed|string
*/
function gitea_user_recent($id_controle, $id_auteur, $options) {
// Initialisation de l'erreur à chaine vide soit 'aucune erreur'.
$erreur = '';
// Construction de l'url de la requête de récupération de tous les users de la forge
include_spip('services/gitea');
$parametres = array(
'admin',
'users'
);
$url = gitea_construire_url($parametres);
// Requête, gestion des erreurs et traitement des users
$reponse = gitea_requeter($url);
if (!empty($reponse['erreur'])) {
$erreur = $reponse['erreur'];
} else {
// On retraite le tableau de façon à pouvoir classer les users du plus récent au plus ancien.
// Pour cela on utilise l'id.
$users = array_column($reponse['donnees'], null, 'id');
krsort($users);
// On extrait les n premiers users du tableau qui sont donc les plus récents
$users_recents = array_slice($users, 0, intval($options['nb_users']));
// On passe les deux tableaux users en chaine JSON avant la mise en cache
$contenu = json_encode($users);
$contenu_recents = json_encode($users_recents);
// Création des fichiers cache pour chaque contenu
// -- Cache de tous les users
include_spip('inc/ezcache_cache');
$cache = array(
'liste' => 'all'
);
cache_ecrire('contrib', 'user', $cache, $contenu);
// -- Cache des users récents
$cache['liste'] = 'last';
cache_ecrire('contrib', 'user', $cache, $contenu_recents);
}
return $erreur;
}

50
ezcheck/controles/gitea_orga_repos.yaml

@ -0,0 +1,50 @@
# Description du type de contrôle:
# --------------------------------
# -- nom: nom littéral du type de contrôle en texte ou item de langue (facultatif, défaut: identifiant du type de contrôle)
# -- description: texte en item de langue ou en chaine (facultatif, défaut: vide)
# -- icone: chemin de l'icone limité à son nom de fichier car recherché dans le thème privé (facultatif, défaut: controle_defaut-24.png)
nom: '<:contrib:type_controle_orga_repos_nom:>'
description: '<:contrib:type_controle_orga_repos_desc:>'
icone: 'rubrique-24.png'
# Fonction PHP d'exécution du contrôle: objet 'execution'
# -------------------------------------------------------
# -- include: indique le chemin relatif du fichier dans le path, sans extension car toujours PHP, dans lequel est incluse
# la fonction (facultatif, défaut: vide). Si le champ n'est pas fourni c'est que le type de contrôle
# est sans fonction de contrôle. Trois formats sont autorisés:
# - '/nom_fichier' indique que le fichier est dans le répertoire relatif par défaut, soit 'ezcheck/controles/'.
# - 'dir_relatif/nom_fichier' indique qu'il faut utiliser le chemin relatif fourni tel que.
# - 'nom_fichier' indique que le fichier est à la racine d'un dossier du path (cas particulier du précédent).
# -- fonction: indique le nom de la fonction d'exécution du contrôle (facultatif, défaut: identifiant du type de contrôle).
# L'utilisation de la valeur par défaut est nécessaire pour gérer les observations et recevoir la liste des
# arguments standard, à savoir, l'id du type de contrôle, l'auteur et les paramètres fonction du formulaire.
# -- parametres: liste ordonnée des paramètres de la fonction définie sous forme d'une liste de saisies.
# On peut passer des paramètres 'fixes' avec une saisie de type hidden.
execution:
include: '/gitea_controle'
# Anomalies & corrections: objet 'anomalies'
# ------------------------------------------
# -- include: indique le chemin relatif du fichier dans le path, sans extension car toujours PHP, dans lequel sont incluses
# les fonctions de correction automatique des anomalies.
# Si le champ est vide ou non fourni et que des corrections existent, c'est que l'include coincide avec celui
# de la fonction d'exécution du type de contrôle.
# Sinon, le format est identique à celui de la fonction d'exécution.
# -- corriger: liste des identifiants d'anomalies que l'on peut corriger (facultatif, défaut: vide)
# -- acquitter: liste des identifiants d'anomalies que l'on peut acquitter (facultatif, défaut: vide)
# Affichage complémentaire HTML: objet 'affichage'
# ------------------------------------------------
# -- squelette: indique le chemin relatif du fichier dans le path, sans extension car toujours HTML.
# -- contexte: liste des variables supplémentaires de contexte à passer au squelette
# -- parametres: liste des paramètres du squelette définie sous forme d'une liste de saisies.
# On peut passer des paramètres en plus des variables fixes de contexte, toute sera inséré dans
# l'environnement du squelette
affichage:
squelette: 'prive/squelettes/liste/caches'
contexte:
plugin: 'contrib'
type_cache: 'repo'
titre: '<:contrib:repo_organisation_titre:>'
sinon: '<:contrib:repo_organisation_sinon:>'
avec_telechargement: 'oui'

14
ezcheck/controles/gitea_user_recent.html

@ -0,0 +1,14 @@
[(#REM) Liste des derniers utilisateurs inscrits ]
<INCLURE{fond=prive/squelettes/liste/users,
users=#CACHE_LISTE{contrib, #ARRAY{type_cache, user, liste, last}},
env} />
[(#REM) Liste des caches : en fait uniquement le fichier users_all.json qui sera téléchargeable ]
<INCLURE{fond=prive/squelettes/liste/caches,
plugin=contrib,
type_cache=user,
filtres=#ARRAY{liste, all},
titre=<:contrib:user_gitea_titre:>,
sinon=<:contrib:user_gitea_sinon:>,
avec_telechargement=oui,
env} />

50
ezcheck/controles/gitea_user_recent.yaml

@ -0,0 +1,50 @@
# Description du type de contrôle:
# --------------------------------
# -- nom: nom littéral du type de contrôle en texte ou item de langue (facultatif, défaut: identifiant du type de contrôle)
# -- description: texte en item de langue ou en chaine (facultatif, défaut: vide)
# -- icone: chemin de l'icone limité à son nom de fichier car recherché dans le thème privé (facultatif, défaut: controle_defaut-24.png)
nom: '<:contrib:type_controle_user_recent_nom:>'
description: '<:contrib:type_controle_user_recent_desc:>'
icone: 'auteur-24.png'
# Fonction PHP d'exécution du contrôle: objet 'execution'
# -------------------------------------------------------
# -- include: indique le chemin relatif du fichier dans le path, sans extension car toujours PHP, dans lequel est incluse
# la fonction (facultatif, défaut: vide). Si le champ n'est pas fourni c'est que le type de contrôle
# est sans fonction de contrôle. Trois formats sont autorisés:
# - '/nom_fichier' indique que le fichier est dans le répertoire relatif par défaut, soit 'ezcheck/controles/'.
# - 'dir_relatif/nom_fichier' indique qu'il faut utiliser le chemin relatif fourni tel que.
# - 'nom_fichier' indique que le fichier est à la racine d'un dossier du path (cas particulier du précédent).
# -- fonction: indique le nom de la fonction d'exécution du contrôle (facultatif, défaut: identifiant du type de contrôle).
# L'utilisation de la valeur par défaut est nécessaire pour gérer les observations et recevoir la liste des
# arguments standard, à savoir, l'id du type de contrôle, l'auteur et les paramètres fonction du formulaire.
# -- parametres: liste ordonnée des paramètres de la fonction définie sous forme d'une liste de saisies.
# On peut passer des paramètres 'fixes' avec une saisie de type hidden.
execution:
include: '/gitea_controle'
parametres:
- saisie: 'input'
options:
nom: 'nb_users'
label: '<:contrib:user_nb_recent_label:>'
defaut: 30
# Anomalies & corrections: objet 'anomalies'
# ------------------------------------------
# -- include: indique le chemin relatif du fichier dans le path, sans extension car toujours PHP, dans lequel sont incluses
# les fonctions de correction automatique des anomalies.
# Si le champ est vide ou non fourni et que des corrections existent, c'est que l'include coincide avec celui
# de la fonction d'exécution du type de contrôle.
# Sinon, le format est identique à celui de la fonction d'exécution.
# -- corriger: liste des identifiants d'anomalies que l'on peut corriger (facultatif, défaut: vide)
# -- acquitter: liste des identifiants d'anomalies que l'on peut acquitter (facultatif, défaut: vide)
# Affichage complémentaire HTML: objet 'affichage'
# ------------------------------------------------
# -- squelette: indique le chemin relatif du fichier dans le path, sans extension car toujours HTML.
# -- contexte: liste des variables supplémentaires de contexte à passer au squelette
# -- parametres: liste des paramètres du squelette définie sous forme d'une liste de saisies.
# On peut passer des paramètres en plus des variables fixes de contexte, toute sera inséré dans
# l'environnement du squelette
affichage:
squelette: '/gitea_user_recent'

6
ezcheck/dashboards/contrib.yaml

@ -21,3 +21,9 @@ groupes:
- 'contrib_article_prepa'
- 'contrib_article_prop'
- 'contrib_article_refuse'
-
identifiant: 'gitea'
nom: '<:contrib:groupe_contrib_gitea_nom:>'
controles:
- 'gitea_orga_repos'
- 'gitea_user_recent'

13
lang/contrib_fr.php

@ -27,6 +27,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'groupe_contrib_article_nom' => 'Articles',
'groupe_contrib_plugin_nom' => 'Plugins',
'groupe_contrib_rubrique_nom' => 'Rubriques',
'groupe_contrib_gitea_nom' => 'Forge',
// L
'icone_voir_plugin' => 'Voir le plugin',
@ -39,6 +40,8 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
'type_article_actualite_label' => 'article d\'actualité',
// R
'repo_organisation_titre' => 'Fichiers des repos des organisations Gitea',
'repo_organisation_sinon' => 'Aucun fichier disponible',
'rubrique_plugin_generer_prefixe_label' => 'Générer les préfixes des rubriques-plugin',
'rubrique_couleur_label' => 'Couleur de la rubrique',
'rubrique_categorie_synchroniser_texte_label' => 'Synchroniser les rubriques-catégorie',
@ -62,4 +65,14 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
Le contrôle prend pour référence la typologie &#171; catégorie des plugins &#187; qui doit donc être fiabilisée au préalable.
Néanmoins, avant de lancer la correction automatique pour l\'anomalie <code>rubplug_loc</code>, il est conseillé de vérifier que l\'affectation plugin-catégorie est correcte. Si oui, la correction automatique placera la rubrique là où il faut.',
'type_controle_user_recent_nom' => 'Utilisateurs récemment inscrits',
'type_controle_orga_repos_nom' => 'Liste des repos des organisations',
'type_controle_user_recent_desc' => 'Ce contrôle permet de récupérer la liste des users Gitea dans un fichier JSON téléchargeable et affiche la liste des n derniers inscrits, n pouvant être choisi à chaque exécution.',
'type_controle_orga_repos_desc' => 'Ce contrôle génère, pour chaque organisation Gitea, un fichier téléchargeable de la liste des repos sous la forme organisation/repo.',
// U
'user_recent_titre' => '@nb@ derniers users Gitea inscrits',
'user_gitea_titre' => 'Fichier JSON de tous les users Gitea',
'user_gitea_sinon' => 'Fichier JSON non disponible',
'user_nb_recent_label' => 'Choisir le nombre de users à afficher',
);

53
prive/squelettes/liste/users.html

@ -0,0 +1,53 @@
[(#REM) <!-- USERS
Inclusion générique fournissant une liste de users Gitea.
@param array users
Tabelau des users à afficher
@param string par
Champ utilisé pour le tri : date ou nom_cache
@param int nb
Nombre de caches affichés sur la même page (pagination).
-->]
[(#SET{defaut_tri,#ARRAY{
username, 1,
created, -1,
}})]
<BOUCLE_fichier_users(DATA) {source table, #USERS}>
<B_users_recents>
#ANCRE_PAGINATION
<div class="liste-objets users">
<table class="spip liste">
<caption>
<strong class="caption">
<:contrib:user_recent_titre{nb=#GRAND_TOTAL}:>
</strong>
</caption>
<thead>
<tr class="first_row">
<th class="id" scope="col">[(#TRI{id,<:info_numero_abbreviation:>,ajax})]</th>
<th class="nom principale" scope="col">[(#TRI{username,<:info_nom:>,ajax})]</th>
<th class="email" scope="col"><:email:></th>
<th class="date" scope="col">[(#TRI{created,<:date:>,ajax})]</th>
</tr>
</thead>
<tbody>
<BOUCLE_users_recents(DATA)
{source json, #CLE}
{tri #ENV{par, created}, #GET{defaut_tri}}
{pagination #ENV{nb, 10}}>
<tr class="[(#COMPTEUR_BOUCLE|alterner{row_odd, row_even})]">
<td class="id">#ID</td>
<td class="nom principale">#USERNAME</td>
<td class="email">#EMAIL</td>
<td class="date">[(#CREATED|affdate_heure)]</td>
</tr>
</BOUCLE_users_recents>
</tbody>
</table>
[<nav class="pagination">(#PAGINATION{prive})</nav>]
</div>
</B_users_recents>
</BOUCLE_fichier_users>

83
services/gitea.php

@ -0,0 +1,83 @@
<?php
/**
* Ce fichier contient l'ensemble des constantes et des utilitaires nécessaires au fonctionnement du service web Gitea.
*/
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
if (!defined('_GITEA_SPIP_ENDPOINT_BASE_URL')) {
/**
* Préfixe des URL du service web de Gitea SPIP.
*/
define('_GITEA_SPIP_ENDPOINT_BASE_URL', 'https://git.spip.net/api/v1/');
}
/**
* Construit l'URL de la requête Gitea correspondant à la demande utilisateur.
*
* @param array $parametres Liste des paramètres de l'url à accoler dans l'ordre fourni.
*
* @return string L'URL de la requête au service
* @internal
*
*/
function gitea_construire_url($parametres = array()) {
// Récupération du token d'autorisation d'accès à l'API
include_spip('inc/config');
$token = lire_config('contrib/token');
// Construire l'URL de l'api sollicitée
$url = _GITEA_SPIP_ENDPOINT_BASE_URL
. implode('/', $parametres)
. "?access_token=${token}";
return $url;
}
/**
* Renvoie, à partir de l'url du service, le tableau des données demandées.
* Le service utilise dans ce cas une chaine JSON qui est décodée pour fournir
* le tableau de sortie. Le flux retourné par le service est systématiquement
* transcodé dans le charset du site avant d'être décodé.
*
* @uses recuperer_url()
*
* @param string $url URL complète de la requête au service web concerné.
* @param null|int $taille_max Taille maximale du flux récupéré suite à la requête.
* `null` désigne la taille par défaut.
*
* @return array
*/
function gitea_requeter($url, $taille_max = null) {
// Initialisation de la réponse
$reponse = array(
'donnees' => array(),
'erreur' => ''
);
// Acquisition des données spécifiées par l'url
include_spip('inc/distant');
$options = array(
'transcoder' => true,
'taille_max' => $taille_max);
$flux = recuperer_url($url, $options);
$reponse = array();
if (empty($flux['page'])) {
spip_log("URL indiponible : ${url}", 'contrib');
$reponse['erreur'] = 'url_indisponible';
} else {
// Transformation de la chaîne json reçue en tableau associatif
try {
$reponse['donnees'] = json_decode($flux['page'], true);
} catch (Exception $erreur) {
$reponse['erreur'] = 'analyse_json';
spip_log("Erreur d'analyse JSON pour l'URL `${url}` : " . $erreur->getMessage(), 'contrib' . _LOG_ERREUR);
}
}
return $reponse;
}
Loading…
Cancel
Save