Implement `excluded` command to report excluded identities from the WoT / DeathReaper

Tasks

Message generation

### Exclusions de la toile de confiance Ğ1, pertes des statuts de membre
> Message automatique. Merci de notifier vos proches de leur exclusion de la toile de confiance

- [`Williambenhaim`](https://g1.duniter.fr/#/app/block/274234/7D4334A459D6F35A089492D346B07C6711AFB0E8273CE9DCE3BC65C594061A25?ssl=true) :
  - **certifié·e par** Jonelio108, Gauri, Djtina12.
  - **a certifié·e** Jonelio108, Gauri, Djtina12.

- [bloc](https://g1.duniter.fr/#/app/block/278701/4C83465A475FF97AA48125CB8567BD7AE5EFCAE35DEF6819DE22826306C0C5A3?ssl=true) :
  - @Helene:
    - **certifié·e par** @ElenaMoshkina, @bert, @Notfifi, @Floweranne, @Gabychou, @dagasaga, @AnaisTerraFlor.
    - **a certifié·e** Jonelio108, Gauri, Djtina12.
  - @Valentina:
    - **certifié·e par** @ElenaMoshkina, @bert, @Notfifi, @Gabychou, @Floweranne, @AnaisTerraFlor, @dagasaga.
    - **a certifié·e** Jonelio108, Gauri, Djtina12.
  • One post per block/exclusion? Could ease not to loose exclusions around 9AM/PM.
  • The exclusion through WebSocket event would be nice on GVA:
    • Already possible listening on /ws/blocks.
    • exclusions won’t be loose
    • Silkaj would constantly listen to this flow.
    • We could also benefit of having direct notifications.
    • But, Silkaj will not be able to run into a CI/CD job. It would need to run on a server.
  • Request Discourse forum to know if the account exists
    • Remove every request and simply prefix all accounts with a @:
      • This drastically improve the speed and generate much less requests.
      • May be the @ could be extended later on, once the account have been renamed.
  • Generate once the message for the two forums/Ğ1
    • We might only be keep Monnaie libre forum for Ğ1 exclusions
  • Request Cesium+ to get the corresponding name.
  • Ignore revoked identities
  • Handle to start the list X days before now (pass an extra parameter).
  • Display the reason of the exclusion:
    • membership expiration: check membership expiration date
    • lack of certifications: check current number of certifications
  • Date of the exclusion

Forums Publication/CLI

  • Publish on Discourse forums
  • Allow renaming pseudo on the forums
  • Add ability to pass a number of hours. One of the days and hours should be present. Both could be present.
  • Ask with a confirmation to publish or not the message if --publish option is not passed, Keep --publish option.
  • Option(s) to publish on only one of the two forums
  • Stop publishing Ğ1 exclusions on Duniter forum.

Discourse API authentication change

Packaging

  • pydiscourse is not in Debian, this dependency will prevent Silkaj to enter in Debian Bullseye #270 (closed):
    • Create DeathReaper package, and set Silkaj as a dependency:
      • Create client/python/deathreaper git repository/package based on Silkaj: Poetry, CI/CD
    • Introduce a module system in Silkaj:
      • Silkaj could install an extra deathreaper package:
      • The CLI could be extended through Click to add a command, then an import should be enough
    • Implement in DuniterPy the used HTTP REST call: create_post() to replace pydiscourse. Not nice, better let pydiscourse project handle the changes of the API. DuniterPy should stay focuse on Ğ1’s APIs.

Automation

  • Executed at 9 AM and PM for Ğ1 and Ğ1-Test with a cron on my machine
  • #388 (closed): Generate Docker image with Silkaj inside
  • Create clients/python/deathreaper repository to set the automation
    • Executed at 9 AM and PM for Ğ1 and Ğ1-Test
    • Based on the previously generated Docker image
    • Pass the API tokens through the CI secret system
  • Could/Should be kept on a machine if all the time running: in case of listening exclusions on a WS

To do later/Improvements

Open following tickets

  • English translation of the output message?
  • Report joiners (previously excluded) by replying to the post which notifies the exclusion
Edited by Moul