Skip to content

Module contributions : annonce des nouvelles contributions du Drive EPL - #147

Merged
Hokkaydo merged 2 commits into
Hokkaydo:devfrom
thremilien:feature/drive-contributions
Sep 29, 2026
Merged

Hokkaydo merged 2 commits into
Hokkaydo:devfrom
thremilien:feature/drive-contributions

Conversation

@thremilien

Copy link
Copy Markdown
Contributor

Pourquoi

Les contributions déposées dans Contributions EPL-Drive/ passent facilement inaperçues et s'accumulent. Ce module annonce chaque nouveau fichier sur Discord pour qu'elles soient traitées au fil de l'eau.

Ce que fait le module contributions

  • Liste le dossier des contributions via rclone, toutes les heures (CONTRIBUTIONS_UPDATE_PERIOD, en minutes).
  • Annonce chaque nouveau fichier (chemin + taille) dans le salon existant DRIVE_ADMIN_CHANNEL_ID.
  • Mentionne le rôle CONTRIBUTIONS_ROLE_ID (optionnel), une seule fois par passage pour qu'un gros dépôt ne ping pas 30 fois.
  • /contributions (admins, réponse éphémère) liste les fichiers pas encore importés, c'est-à-dire encore présents dans le dossier.

Détails de fonctionnement :

  • Fichiers suivis par identifiant Drive : un fichier sorti du dossier lors d'un import ne déclenche rien, un fichier renommé n'est pas ré-annoncé.
  • Au premier passage (ou si le dossier surveillé change), un seul message récapitulatif « N fichier(s) déjà présent(s) » au lieu d'une annonce par fichier.
  • Si le salon n'est pas défini ou pas accessible, les fichiers restent en attente et sont annoncés dès que possible.
  • Les erreurs (token expiré, dossier introuvable…) sont envoyées une fois dans le salon admin, pas à chaque passage.
  • Les noms de fichiers ne peuvent mentionner personne (@everyone dans un nom de fichier est neutralisé).

Configuration

  • CONTRIBUTIONS_REMOTE (variable d'environnement) : dossier au format rclone, ex. onedrive:Fichiers de Maxime Drooghaag - Drive EPL/Contributions EPL-Drive. En variable d'env plutôt que /config, pour que les admins Discord ne puissent pas pointer vers un autre dossier du OneDrive lié.
  • rclone est ajouté à l'image Docker (rclone/rclone:1), sa config est lue dans persistence/rclone.conf (RCLONE_CONFIG).
  • Procédure complète dans le README : token en lecture seule (--onedrive-access-scopes "Files.Read Files.Read.All Sites.Read.All offline_access"), création du remote via le rclone de l'image, reconnexion si le token expire.

Nouvelles tables SQLite : contribution_files, contribution_remotes. Nouvelles clés /config : CONTRIBUTIONS_ROLE_ID, CONTRIBUTIONS_UPDATE_PERIOD.

⚠️ À discuter avant de merger

  • Accès OneDrive sur le serveur : le token rclone donne accès (en lecture seule si on suit le README) au OneDrive du compte UCLouvain qui l'a créé, et serait stocké dans data/rclone.conf sur le VPS. À valider ensemble : quel compte, et qui fait la mise en place.
  • Le PDF « Contributions Drive EPL - EPL Drive Contribution System.pdf » est en permanence dans le dossier : il est compté au premier message et apparaît dans /contributions. Faut-il l'exclure ?
  • /contributions est réservée aux membres ayant la permission Administrateur ; si les admins du Drive ne l'ont pas, on peut plutôt la limiter au salon DRIVE_ADMIN_CHANNEL_ID.

Tests

Compilé avec Java 25 (image build du Dockerfile). Testé de bout en bout sur un serveur Discord de test avec un dossier OneDrive de test :

  • Premier lancement : un seul message récapitulatif, sans mention
  • Nouveau fichier : annonce avec chemin, taille et mention du rôle
  • 3 fichiers d'un coup : 3 messages, une seule mention ; @everyone dans un nom de fichier ne mentionne personne
  • Fichier sorti du dossier (import) : aucun message
  • /contributions : liste correcte, erreur explicite si le dossier est introuvable, message dédié si vide
  • Salon non défini : une seule erreur dans le salon admin, rattrapage des fichiers en attente une fois le salon défini
  • Mauvais CONTRIBUTIONS_REMOTE : une seule erreur sur 3 passages
  • Redémarrage : aucune ré-annonce
  • Non testé : token lecture seule du README, salon sans permission d'écriture pour le bot

Periodically lists the Drive contributions folder through rclone and
announces each new file in DRIVE_ADMIN_CHANNEL_ID, optionally mentioning
CONTRIBUTIONS_ROLE_ID once per batch. /contributions lists the files not
imported yet.

- Files are tracked by Drive id: files moved out on import trigger nothing
- First listing of a remote only sends a summary message
- Listing errors are reported once in the admin channel
- rclone is added to the runtime image, its config lives in persistence/

@Hokkaydo Hokkaydo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments, and maybe reconsider the use of a repository.

Regarding the general PR message, 2 points are mentioned but not resolved:

  • Le PDF « Contributions Drive EPL - EPL Drive Contribution System.pdf » est en permanence dans le dossier : il est compté au premier message et apparaît dans /contributions. Faut-il l'exclure ?
  • /contributions est réservée aux membres ayant la permission Administrateur ; si les admins du Drive ne l'ont pas, on peut plutôt la limiter au salon DRIVE_ADMIN_CHANNEL_ID.

For the first one, I'd say the file has to be excluded from analysis. For the permission, drive admins do not have the Administrator permission. Rather than limiting the command to admins, it can be allowed for people having the DRIVE_ADMIN_ROLE_ID (to be configured; it doesn't exist yet). Or, instead of allowing every channel for the command, filter by the DRIVE_ADMIN_CHANNEL_ID. The first suggestion is more convenient, but the second one is easier to implement

}
List<String> lines = new ArrayList<>();
lines.add(Strings.getString("contributions.command.header").formatted(files.size()));
files.stream().map(f -> "• %s (%s)".formatted(f.displayPath(), f.displaySize())).forEach(lines::add);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use plain "-" instead of "•"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

boolean isSeeded(long guildId, String remote);

/**
* Records that the existing files of this remote have been recorded for this guild

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wtf does that line even mean

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gone with the repository removal (it recorded that a remote's existing files had been seen, to avoid announcing them all at first run).

* @param remote the rclone remote path
* @return true if the existing files of this remote have already been recorded for this guild
* */
boolean isSeeded(long guildId, String remote);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why "isSeeded" ? what does it mean

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed along with the repository, see the reply on line 8.


import java.util.Set;

public interface ContributionFileRepository extends CRUDRepository<ContributionFile> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if that whole repository is required at all. It seems to store unnecessary data. Maybe consider using the already existing system of Guild Variable through ConfigurationRepository#getGuildState and storing only the creation date of the last processed file instead of storing useless file IDs over and over

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, removed. It now stores only CONTRIBUTIONS_LAST_UPLOAD in guild state, using OneDrive's upload time (utime, via rclone lsjson --metadata) rather than the modification time, which keeps the uploader's local date.

private static String truncate(String message) {
if (message == null) return "";
// Keep the end: rclone's last lines hold the actual reason of the failure
return message.length() > MAX_ERROR_LENGTH ? "…" + message.substring(message.length() - MAX_ERROR_LENGTH) : message;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use 3 dots instead of the ellipsis, it might not render properly in some cases

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

try {
check();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case abort the module's initialisation and warn about it, since its only caused by a missing env var

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: the module no longer enables if CONTRIBUTIONS_REMOTE is missing, and warns in the logs and the admin channel.

Comment thread README.md Outdated
- `GITHUB_APPLICATION_ID`: Identifiant de l'application Github liée (permet de gérer les issues) *(Optionnel)*
- `GITHUB_APPLICATION_INSTALLATION_ID`: Identifiant d'installation de l'application Github liée (permet de gérer les issues) *(Optionnel)*
- `HASTEBIN_TOKEN`: Jeton d'identification auprès de l'API de Hastebin
- `CONTRIBUTIONS_REMOTE`: Dossier des contributions du Drive EPL au format rclone, ex. `onedrive:Fichiers de Maxime Drooghaag - Drive EPL/Contributions EPL-Drive` *(Optionnel, module `contributions`)*

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not mention explicit names (remove the example or abstract the name)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, replaced with a placeholder.

…LE_ID, exclude contribution system PDF

- Replace the contribution file repository and tables with a single CONTRIBUTIONS_LAST_UPLOAD guild state, based on OneDrive upload time (rclone --metadata utime)
- Allow /contributions for members with the new DRIVE_ADMIN_ROLE_ID role (and administrators)
- Exclude the permanent contribution system PDF from the listing
- Do not enable the module and warn when CONTRIBUTIONS_REMOTE is not set
- Use plain ASCII characters, remove explicit names from README
@thremilien

Copy link
Copy Markdown
Contributor Author

Thanks for the review, all addressed in e85213b:

  • The contribution system PDF is excluded from the analysis.
  • /contributions is now available to members with the new DRIVE_ADMIN_ROLE_ID role (and administrators). It needs to be set with /config.

@Hokkaydo
Hokkaydo merged commit f645687 into Hokkaydo:dev Sep 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants