diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..da94bde --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.env +# Bot/.env +extends +.pyc diff --git a/.gitignore b/.gitignore index e307f0a..3a750ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ -__pycache__ -src/bot/cogs/ - -src/bot/.idea/ - -src/urpy/.idea/ +test.yml +compose-build.yml +docker-compose-merge.yml + +__pycache__/ + +.env +# not load env file +env/* +#invert to keep default .env (keep the default.*) +!env/default* \ No newline at end of file diff --git a/Discord-Bot-main/Bot/.env b/Discord-Bot-main/Bot/.env deleted file mode 100644 index a979cc9..0000000 --- a/Discord-Bot-main/Bot/.env +++ /dev/null @@ -1 +0,0 @@ -TOKEN=MTA0MDI3NTE3NTY4NzYwNjM3Mg.GRMHqA.yEreIkPlGQh4wMWz5_TK3yLPf3ygEMfGCYrwmk diff --git a/Discord-Bot-main/Bot/DebugBot.py b/Discord-Bot-main/Bot/DebugBot.py deleted file mode 100644 index 4cc5d90..0000000 --- a/Discord-Bot-main/Bot/DebugBot.py +++ /dev/null @@ -1,45 +0,0 @@ - - -from importlib import reload -import asyncio -import event -import types - - - -# décaration d'un décorateur a fonction (@update_module(module_name)) -def update_module(module): - def __update__(func): - async def callback(*args, **kwargs): - reload(__import__(module,globals(), locals(), [], 0)) # (recherche le module pour voir si il est déà chargé sinon il import dynamiquement) puis la fonction reload recharge le module - return await func(*args, **kwargs) - - return (callback) - - return __update__ - - -def update_all_modules(func): - async def __update__(*args, **kwargs): - for name, val in globals().items(): - if isinstance(val, types.ModuleType): - print(val.__name__) - reload(__import__(val.__name__,globals(), locals(), [], 0)) - - reload(__import__("DebugBot",globals(), locals(), [], 0)) - - return await func(*args, **kwargs) - - return __update__ - -async def debug_on_message(*args,**kwargs): - return await event.on_message(*args,**kwargs) - -async def debug_on_ping(*args,**kwargs): - return await event.on_ping(*args,**kwargs) - -async def debug_on_prez(*args,**kwargs): - return await event.on_prez(*args,**kwargs) - -async def debug_on_help(*args,**kwargs): - return await event.on_help(*args,**kwargs) diff --git a/Discord-Bot-main/Bot/UR-Bot.py b/Discord-Bot-main/Bot/UR-Bot.py deleted file mode 100644 index 50727e3..0000000 --- a/Discord-Bot-main/Bot/UR-Bot.py +++ /dev/null @@ -1,69 +0,0 @@ -import discord -from dotenv import load_dotenv -import DebugBot -from discord.ext import commands -import os - - - -load_dotenv() -TOKEN = os.getenv('TOKEN') - -class UR_BOT(commands.Bot): - - async def on_ready(self): - print('--- We have successfully loggged in as {0.user}'.format(self)) - - async def on_message(self, message): - - if message.author == self.user: - return - - await DebugBot.debug_on_message(message); - - return await bot.process_commands(message) - - - - -intent = discord.Intents.default() -intent.members = True -intent.messages = True - -bot = UR_BOT(command_prefix= DebugBot.event.BOT_PREFIX,intents=intent) -bot.remove_command('help') - - - -@bot.command(name="ping") -@commands.guild_only() -async def ping(ctx): - await DebugBot.debug_on_ping(ctx) - - - - -@bot.command(name="help") -async def help(ctx): - await DebugBot.debug_on_help(ctx) - -@bot.command(name="prez") -async def prez(ctx): - await DebugBot.debug_on_prez(ctx) - - -@DebugBot.update_all_modules -async def reload_module(): - return 0; - - - -@bot.command(aliases=['reload', 'rld']) -async def reload_module(ctx): - await reload_module(); - await ctx.channel.send("The scripts has been reloaded."); - return 0; - - -bot.run(TOKEN) - diff --git a/Discord-Bot-main/Bot/event.py b/Discord-Bot-main/Bot/event.py deleted file mode 100644 index bd5803d..0000000 --- a/Discord-Bot-main/Bot/event.py +++ /dev/null @@ -1,147 +0,0 @@ - -import asyncio -import discord - -BOT_PREFIX = "$" - - -HELP_DATA = { - "About": - { - "cmd_0": - { - "cmd": "credit", - "help": "Affiche les crédits" - }, - - "cmd_1": - { - "cmd": "version", - "help": "Affiche les numéros de version" - }, - }, - - "General": - { - "cmd_0": - { - "cmd": "cancel", - "help": "Annule l'action en cours" - }, - - "cmd_1": - { - "cmd": "done", - "help": "Confirme l'action en cours" - }, - - "cmd_2": - { - "cmd": "edit", - "help": "Édite un message" - }, - - "cmd_3": - { - "cmd": "lang", - "help": "Change la langue de l'utilisateur" - }, - }, - - "Planning": - { - "cmd_0": - { - "cmd": "cal", - "help": "Permet d'accéder au calendrier" - }, - - "cmd_1": - { - "cmd": "jdr", - "help": "Envoie un lien pour créer une partie" - }, - - "cmd_2": - { - "cmd": "site", - "help": "Permet d'accéder au calendrier" - }, - - }, - - "Presentation": - { - "cmd_0": - { - "cmd": "prez", - "help": "Envoie un lien pour se présenter" - }, - }, - - "No Category": - { - "cmd_0": - { - "cmd": "help", - "help": "Affiche ce message" - }, - } - -}; - - -def GetMaxStrSizeInArray(array:dict,callback=None): - _size=0; - for cmd in array: - _r = callback(cmd) - if(_r > _size): - _size = _r - return _size - - -async def on_ping(event): - await event.author.send("pong"); - - - -async def on_message(event,*args,**kwargs): - if event.content.startswith('hi'): - await event.channel.send(f'Hello! Mis a jour : {args}') - -async def on_prez(event,*args,**kwargs): - embed = discord.Embed(url="http://presentation.unionrolistes.fr/?webhook=https://discord.com/api/webhooks/875068900612665396/DJusy0eGs9Xyx2os-dodBVfWia2fbhfBzfmnDM9g-30ozoFYAuZBHVXaD9TKaC1wwBwg", description="⬆️ Here is the link to create your presentation.", title="Union Roliste - Presentation", color= 0x0CC1EE) - embed.set_author(name=event.author.display_name, icon_url=event.author.avatar_url) - - DATA = ["**:pen_ballpoint: Nom\n**","**:pen_ballpoint: Prenom\n**",":round_pushpin: **Address\n**",":telephone: **N° Telephone\n**", ":postbox: **Code postal\n**","**:computer: Support (Windows / Linux / Mac)\n**","**Expérience en programmation\n**"] - embed.add_field(name="**\n**", value="**───────────────────────────────**", inline=False) - - embed.set_footer(text="Union Roliste dev presentation.", icon_url="https://avatars.githubusercontent.com/u/62179928?s=200&v=4") - - embed.set_thumbnail(url="https://avatars.githubusercontent.com/u/62179928?s=200&v=4") - - await event.author.send(embed=embed) # envoie un message de presentation privée à l'auteur qui a fait a commandes - -async def on_help(event,*args): - embed = discord.Embed(title="URBOT - helper", color= 0x0CC1EE) - embed.set_author(name="UR-BOT", icon_url="https://cdn.discordapp.com/avatars/1040275175687606372/33d5a8782c1d658caeeae59799e722b0.webp?size=32") - - HELP = str(f"**prefix : {BOT_PREFIX}**\n\n\t```diff\n") - for x in HELP_DATA.items(): - HELP += f"\r+ {x[0]}\n\n\t" - c = GetMaxStrSizeInArray(x[1].items(),lambda a : a[1]['cmd'].__len__()) # Obtenir la chaine la plus longe pour ensuite center la fleche (->) - for cmd in x[1].items(): - _offset = (c - cmd[1]["cmd"].__len__())+1 # centrage de lq flèche (->) - HELP += cmd[1]["cmd"]+ (" "*_offset) + "-> "+cmd[1]["help"]+"\n\t" # Ecrit la command -> description - - HELP += f"\n```" - - embed.add_field(name="**\n**", value="**───────────────────────────────**", inline=False) - - embed.add_field(name="**\n**", value=HELP, inline=False) - - embed.set_footer(text="Union Roliste commands helper.", icon_url="https://avatars.githubusercontent.com/u/62179928?s=200&v=4") - - embed.set_thumbnail(url="https://avatars.githubusercontent.com/u/62179928?s=200&v=4") # set le logo en haut a droit - - await event.channel.send(embed=embed); diff --git a/Discord-Bot-main/Bot/requirements.txt b/Discord-Bot-main/Bot/requirements.txt deleted file mode 100644 index 28fddf9..0000000 Binary files a/Discord-Bot-main/Bot/requirements.txt and /dev/null differ diff --git a/Discord-Bot-main/Install/Dockerfile b/Discord-Bot-main/Install/Dockerfile deleted file mode 100644 index 8002204..0000000 --- a/Discord-Bot-main/Install/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM python:3.7-alpine -WORKDIR UR-BOT-PROJECT -RUN apk add --no-cache gcc musl-dev linux-headers -COPY requirements.txt requirements.txt -RUN apk update -RUN apk add git -RUN pip3 install -r requirements.txt -ENTRYPOINT ["python3", "UR-Bot.py"] diff --git a/Discord-Bot-main/Install/Install.ps1 b/Discord-Bot-main/Install/Install.ps1 deleted file mode 100644 index 8d7f85b..0000000 --- a/Discord-Bot-main/Install/Install.ps1 +++ /dev/null @@ -1,46 +0,0 @@ -Param( - - [Parameter(Mandatory,ValueFromPipeline,HelpMessage='Enter image name type = String)')] - [Alias('image','image_name','in')] - [string] - $ImageName, - - [Parameter(Mandatory,ValueFromPipeline,HelpMessage='Enter container name (type = String)')] - [Alias('container','container_name','cn')] - [string] - $ContainerName, - - [Parameter(Mandatory = $false,ValueFromPipeline=$false)] - [Alias('run','start','st','rn')] - [Switch]$gorun - -) # On r�cup�re les param�tre - -if($ImageName.Length -lt 3) -{ - $error = [string]"The image name length must be than or equal of 4" - Write-Error -Message $error -Category InvalidArgument - return; -} # On check si la longueur de ImageName est < que 4 - -if($ContainerName.Length -lt 3) -{ - $error = [string]"The container name length must be than or equal of 4" - Write-Error -Message $error -Category InvalidArgument - return; - -} # On check si la longueur du ContainerName est < que 4 - -$env:ENV_IMAGE_NAME = $ImageName # l'image pour le docker-compose.yml -$env:ENV_CONTAINER_NAME = $ContainerName # le nom du containeur pour le docker-compose.yml - -docker build . -t $ImageName - -docker compose -p $ContainerName create --no-recreate # On monte le containeur - -if($gorun.IsPresent) -{ - # cls - docker start -a -i $ContainerName - -} # Si on run ou pas (-run / -start) diff --git a/Discord-Bot-main/Install/LaunchInstall.bat b/Discord-Bot-main/Install/LaunchInstall.bat deleted file mode 100644 index 4a7e6ee..0000000 --- a/Discord-Bot-main/Install/LaunchInstall.bat +++ /dev/null @@ -1 +0,0 @@ -powershell -exec bypass .\Install.ps1 -image_name ur-bot-image-ubuntu -container_name ur-bot-container -run diff --git a/Discord-Bot-main/Install/docker-compose.yml b/Discord-Bot-main/Install/docker-compose.yml deleted file mode 100644 index ab183e9..0000000 --- a/Discord-Bot-main/Install/docker-compose.yml +++ /dev/null @@ -1,11 +0,0 @@ -version: '3' - -services: - os: - image: ${ENV_IMAGE_NAME} - container_name: ${ENV_CONTAINER_NAME} - stdin_open: true # docker run -i - tty: true # docker run -t - hostname: ${ENV_CONTAINER_NAME} - volumes: - - ../Bot:/UR-BOT-PROJECT diff --git a/Discord-Bot-main/Install/requirements.txt b/Discord-Bot-main/Install/requirements.txt deleted file mode 100644 index 28fddf9..0000000 Binary files a/Discord-Bot-main/Install/requirements.txt and /dev/null differ diff --git a/Discord-Bot-main/README.md b/Discord-Bot-main/README.md deleted file mode 100644 index 91c1d98..0000000 --- a/Discord-Bot-main/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Discord-Bot - -###### doc : https://discordpy.readthedocs.io/en/stable/api.html?highlight=on_message#discord.Guild.get_channel - -# Instalation - -> **Télécharger** ![Docker](docker.com) -> -> **Télécharger** ![Discord-Bot-main](https://github.com/UnionRolistes/Bot_Base/tree/11-cree-une-application-docker-pour-facilit%C3%A9-le-developpement/Discord-Bot-main) -> -> **Lancer le script** ![LaunchInstall.bat](https://github.com/UnionRolistes/Bot_Base/blob/11-cree-une-application-docker-pour-facilit%C3%A9-le-developpement/Discord-Bot-main/Install/LaunchInstall.bat) dans [Powershell](https://learn.microsoft.com/fr-fr/powershell/scripting/overview?view=powershell-7.3) -> -> **Fini !. Le script (LaunchInstall.bat) lancera automatiquement le container et par concequant le bot discord** -> -> -> **Commandes disponible :** -> -> - **$prez** -> - **$help** -> - **$ping** - diff --git a/README.md b/README.md index a2b4fe2..c07ccae 100755 --- a/README.md +++ b/README.md @@ -1,128 +1,53 @@ -[![forthebadge](https://forthebadge.com/images/badges/cc-nc-sa.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/made-with-python.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/made-with-markdown.svg)](https://forthebadge.com) ![](https://img.shields.io/badge/Made%20For-DISCORD-blue) -## Bot Python (UR-Bot) - -[TOCM] - -[TOC] - - -``` -├── Description du projet -├── Languages utilisés -├── Credit , participant, organisation -| -├── 1) Bot Base -│ ├── - But -│ ├── -Installation -│ └── - Usage -| -├── 2.1) Bot-Prez -│ ├── - But -│ ├── - Installation -│ └── - Usage -| -├── 2.2) WebPrez -| -├── 3.1) Bot-planning -| ├── - But -| ├── - Installation -| └── - Usage -| -├── 3.2) Web-Planning -├── - But -├── - Installation -└── - Usage -``` - - - -## Description -> Le BotPresentation(Python3.7) permet à un utilisateur d'accéder à un formulaire de présentation via la commande $prez. Les informations saisies sont ensuite mises en forme et postées sur le discord de l'union des Rôlistes via un Webhook dans la section #presentation - -## Languages utilisés - - Py ( Python ) - - XML ( eXtensible Markup Language ) - - HTML ( eXtensible Markup Language ) - - CSS ( eXtensible Markup Language ) - - sh ( Bash ) - - -Credits -> [credits.md](https://github.com/UnionRolistes/Bot_Base/blob/main/credits.md) - - -# 1) Bot Base - -###### https://github.com/UnionRolistes/Bot_Base - Bot_Base est un repo commun aux autres projet. -Il permet de simplifier l'installation d'un ou plusieurs éléments. - ### Installation - **Pour une 1ère installation** : ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" ``` - - **Pour une mise à jour** : ``` "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh" ``` - - How to setup URbot - The discord bot for managing servers dedicated to rpgs - --- - ##### - 1 ) Install a linux based OS (we'll be using Debian as a reference) - - ##### - 2 ) Install git - - ##### - 3 ) ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" ``` - - **It installs the bot and the 2 sub features** : - - 1. Bot_Planning and Web_Planning - 2. Bot_Presentation and Web_Presentation - - ##### - 4 ) If you want to choose the features to install --> ```"cd /usr/local/src/Bot_Base && sudo git pull && sudo bash install.sh" Then "sudo bash " ``` - - ##### - 5 ) Start the bot and the web sites with "cd/usr/local/src/Bot_Base && sudo bash start.sh && sudo service apache2 restart " - -# 2.1) Bot-Prez - - ###### https://github.com/UnionRolistes/Bot_Presentation - Le BotPresentation(Python3.7) permet à un utilisateur d'accéder à un formulaire de présentation via la commande $prez. Les informations saisies sont ensuite mises en forme et postées sur le discord de l'union des Rôlistes via un Webhook dans la section #presentation - - ![](https://github.com/UnionRolistes/Bot_Base/blob/main/img/BotPresentation_Grafcet-page-001.jpg?raw=true) - ![](https://github.com/UnionRolistes/Bot_Base/blob/main/img/BotPresentation_Grafcet-page-002.jpg?raw=true) - - ### Installation - - **Pour une 1ère installation** : ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" ``` - ---- - -- **Pour une mise à jour** : ``` "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh" ``` - -# 2.2) WebPrez - -# 3.1) Bot-planning - > - ###### https://github.com/UnionRolistes/Bot_Planning_python - - > - Le BotPlanning(Python3.7) et FormulaireJdR (HTML CSS PHP) est un projet lancé a l'initiative de l'Union des Rôlistes (**http://unionrolistes.fr**) un bot discord capable de générer des messages correctement mis en forme, annoncant de prochaine partie de JdR, quel soit physique ou a distance. actuellement les message finaux sont visible sur le discord de l'union des Rôlistes via un Webhook dans la section #Planning-JdR . - - ### Installation - - **Pour une 1ère installation** : "cd /usr/local/src && sudo git clone **https://github.com/UnionRolistes/Bot_Base** && cd Bot_Base && sudo bash updateBot.sh" - -**Pour une mise à jour** : "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh" - -**how to use (in discord)** une fois sur votre serveur discord, et apres avoir vérifier que le bot (ou role des bot) pouvais ecrire dans le canal où vous vous trouvez ecrivez $cal la commande s'effacera, puis vous receverez un message privé avec les instruction. - -# 3.2) Web-Planning - - ###### https://github.com/UnionRolistes/Web_Planning - #### Web_Planning : Formulaire de création de partie - Le formulaire permet a un animateur (MJ) de proposer une session de JdR sur un serveur discord. Via la commande $jdr, il recoit un lien vers un formulaire, avec diverses entrées. Une fois le formulaire completé et validé, celui ci est envoyé vers le discord, et l'annonce mise en forme est alors disponible sur le discord dans le canal #planning-jdr, les joueurs potentiels peuvent alors lire et réagir pour s'y inscrire. Ensuite le MJ peut les contacter pour les informations supplémentaires, telles que la creation de personnage. - - #### Web_Planning : Calendrier - Calendrier web affichant les parties prévues. Via la commande $cal l'utilisateur reçoit le lien du calendrier Ce calendrier affiche horizontalement les parties prévues, par semaine ou par mois. Cliquer sur un événement donnera accès à plus de détails sur la partie, ainsi qu'un lien vers le message discord pour pouvoir s'y inscrire. Les administrateurs ont accès à une section permettant de pré remplir le formulaire avec les données d'une partie déjà existante, afin de la dupliquer. Ils peuvent aussi afficher tous les détails d'une partie selon une mise en forme leur permettant de copier facilement le texte pour une exportation sur les réseaux sociaux - - ### Installation - **Pour une 1ère installation** : ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" sudo nano /var/www/html/Web_Planning/php/config.php.default" ``` --> Remplir ce fichier avec le Client ID, Secret ID et Redirect_URI du Bot, trouvable sur Discord developer (**https://discord.com/developers/applications**) - -``` sudo nano /etc/apache2/sites-available/100-UR_Planning.conf``` --> Remplacer "serverName planning.unionrolistes.fr" (ligne 9) par la redirection saisie sur votre hébergeur en ligne - -**Pour une mise à jour** : ``` "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh"``` - -# TODO -https://github.com/orgs/UnionRolistes/projects/1/views/1 +# Union des Roliste base : bot / api / web + [doc lib](https://discordpy.readthedocs.io/en/stable/api.html?highlight=on_message#discord.Guild.get_channel) + +## Instalation + +- Install [Docker](https://docs.docker.com/desktop/) (only need engine and compose) +- dowload repo + +## first use (or if you want to change the token) + +- [tuto](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) to get your token +- change the token in the .env file + +## use + +- start : `docker-compose up --build -d` (in terminal in path of the project) +- log : `docker-compose logs -f` (in terminal in path of the project) +- stop : `docker-compose down` (in terminal in path of the project) + +## use other repo to extend the bot + +- go to parent folder of the bot +- clone repo needed +- merge docker-compose with `docker-compose -f docker-compose.yml -f ../repo-x/docker-compose.yml config > docker-compose-merge.yml` + > add `-f repo-y/docker-compose.yml` for each repo +- start command here (dev for prod future script) + - `docker-compose -f .\docker-compose.yml -f ..\Bot_Presentation\docker-compose.yml -f ..\Bot_Planning_python\bot\docker-compose.yml config >test.yml` + - `docker-compose -f test.yml up --build -d` + +## Commandes disponible dans le bot base + +- `$help` : show all command available +- `$ping` : show pong and time to respond ( test if bot is alive ) + + + +## dev + +### web + +pour travailler en local penser a faire mentir le dns de votre machine pour que le nom de domaine voulu pointe la ou il faut + +- windows : `C:\WINDOWS\system32\drivers\etc\hosts` +- linux : `/etc/hosts` + +## Développer sous windows sans utiliser docker +L'utilisation du lien symbolique est la meilleur solution dans ce cas. +car copier-coler a chaque fois ou git submodule sont des solution plus compliquer a tester pour dev. +Cette méthode est conseillée quand on travaille sur un plugin. +Exemple: +```cmd + cmd /c mklink /D ..\Bot_Base\bot\extends\Presentation ..\..\..\Bot_Presentation\bot\extends +``` \ No newline at end of file diff --git a/README_old.md b/README_old.md new file mode 100644 index 0000000..f6efafb --- /dev/null +++ b/README_old.md @@ -0,0 +1,128 @@ +[![forthebadge](https://forthebadge.com/images/badges/cc-nc-sa.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/made-with-python.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/made-with-markdown.svg)](https://forthebadge.com) ![](https://img.shields.io/badge/Made%20For-DISCORD-blue) +## Bot Python (UR-Bot) + +[TOCM] + +[TOC] + + +``` +├── Description du projet +├── Languages utilisés +├── Credit , participant, organisation +| +├── 1) Bot Base +│ ├── - But +│ ├── -Installation +│ └── - Usage +| +├── 2.1) Bot-Prez +│ ├── - But +│ ├── - Installation +│ └── - Usage +| +├── 2.2) WebPrez +| +├── 3.1) Bot-planning +| ├── - But +| ├── - Installation +| └── - Usage +| +├── 3.2) Web-Planning +├── - But +├── - Installation +└── - Usage +``` + + + +## Description +> Le BotPresentation(Python3.7) permet à un utilisateur d'accéder à un formulaire de présentation via la commande $prez. Les informations saisies sont ensuite mises en forme et postées sur le discord de l'union des Rôlistes via un Webhook dans la section #presentation + +## Languages utilisés + - Py ( Python ) + - XML ( eXtensible Markup Language ) + - HTML ( eXtensible Markup Language ) + - CSS ( eXtensible Markup Language ) + - sh ( Bash ) + + +Credits -> [credits.md](https://github.com/UnionRolistes/Bot_Base/blob/main/credits.md) + + +# 1) Bot Base + +###### https://github.com/UnionRolistes/Bot_Base + Bot_Base est un repo commun aux autres projet. +Il permet de simplifier l'installation d'un ou plusieurs éléments. + ### Installation + **Pour une 1ère installation** : ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" ``` + + **Pour une mise à jour** : ``` "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh" ``` + + How to setup URbot - The discord bot for managing servers dedicated to rpgs + --- + ##### - 1 ) Install a linux based OS (we'll be using Debian as a reference) + + ##### - 2 ) Install git + + ##### - 3 ) ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" ``` + + **It installs the bot and the 2 sub features** : + + 1. Bot_Planning and Web_Planning + 2. Bot_Presentation and Web_Presentation + + ##### - 4 ) If you want to choose the features to install --> ```"cd /usr/local/src/Bot_Base && sudo git pull && sudo bash install.sh" Then "sudo bash " ``` + + ##### - 5 ) Start the bot and the web sites with "cd/usr/local/src/Bot_Base && sudo bash start.sh && sudo service apache2 restart " + +# 2.1) Bot-Prez + + ###### https://github.com/UnionRolistes/Bot_Presentation + Le BotPresentation(Python3.7) permet à un utilisateur d'accéder à un formulaire de présentation via la commande $prez. Les informations saisies sont ensuite mises en forme et postées sur le discord de l'union des Rôlistes via un Webhook dans la section #presentation + + ![](https://github.com/UnionRolistes/Bot_Base/blob/main/img/BotPresentation_Grafcet-page-001.jpg?raw=true) + ![](https://github.com/UnionRolistes/Bot_Base/blob/main/img/BotPresentation_Grafcet-page-002.jpg?raw=true) + + ### Installation + + **Pour une 1ère installation** : ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" ``` + +--- + +- **Pour une mise à jour** : ``` "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh" ``` + +# 2.2) WebPrez + +# 3.1) Bot-planning + > - ###### https://github.com/UnionRolistes/Bot_Planning_python + + > - Le BotPlanning(Python3.7) et FormulaireJdR (HTML CSS PHP) est un projet lancé a l'initiative de l'Union des Rôlistes (**http://unionrolistes.fr**) un bot discord capable de générer des messages correctement mis en forme, annoncant de prochaine partie de JdR, quel soit physique ou a distance. actuellement les message finaux sont visible sur le discord de l'union des Rôlistes via un Webhook dans la section #Planning-JdR . + + ### Installation + + **Pour une 1ère installation** : "cd /usr/local/src && sudo git clone **https://github.com/UnionRolistes/Bot_Base** && cd Bot_Base && sudo bash updateBot.sh" + +**Pour une mise à jour** : "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh" + +**how to use (in discord)** une fois sur votre serveur discord, et apres avoir vérifier que le bot (ou role des bot) pouvais ecrire dans le canal où vous vous trouvez ecrivez $cal la commande s'effacera, puis vous receverez un message privé avec les instruction. + +# 3.2) Web-Planning + + ###### https://github.com/UnionRolistes/Web_Planning + #### Web_Planning : Formulaire de création de partie + Le formulaire permet a un animateur (MJ) de proposer une session de JdR sur un serveur discord. Via la commande $jdr, il recoit un lien vers un formulaire, avec diverses entrées. Une fois le formulaire completé et validé, celui ci est envoyé vers le discord, et l'annonce mise en forme est alors disponible sur le discord dans le canal #planning-jdr, les joueurs potentiels peuvent alors lire et réagir pour s'y inscrire. Ensuite le MJ peut les contacter pour les informations supplémentaires, telles que la creation de personnage. + + #### Web_Planning : Calendrier + Calendrier web affichant les parties prévues. Via la commande $cal l'utilisateur reçoit le lien du calendrier Ce calendrier affiche horizontalement les parties prévues, par semaine ou par mois. Cliquer sur un événement donnera accès à plus de détails sur la partie, ainsi qu'un lien vers le message discord pour pouvoir s'y inscrire. Les administrateurs ont accès à une section permettant de pré remplir le formulaire avec les données d'une partie déjà existante, afin de la dupliquer. Ils peuvent aussi afficher tous les détails d'une partie selon une mise en forme leur permettant de copier facilement le texte pour une exportation sur les réseaux sociaux + + ### Installation + **Pour une 1ère installation** : ``` "cd /usr/local/src && sudo git clone https://github.com/UnionRolistes/Bot_Base && cd Bot_Base && sudo bash updateBot.sh" sudo nano /var/www/html/Web_Planning/php/config.php.default" ``` --> Remplir ce fichier avec le Client ID, Secret ID et Redirect_URI du Bot, trouvable sur Discord developer (**https://discord.com/developers/applications**) + +``` sudo nano /etc/apache2/sites-available/100-UR_Planning.conf``` --> Remplacer "serverName planning.unionrolistes.fr" (ligne 9) par la redirection saisie sur votre hébergeur en ligne + +**Pour une mise à jour** : ``` "cd /usr/local/src/Bot_Base && sudo git checkout . && sudo git pull && sudo bash updateBot.sh"``` + +# TODO +https://github.com/orgs/UnionRolistes/projects/1/views/1 diff --git a/add_repo.sh b/add_repo.sh deleted file mode 100644 index 5f00a4a..0000000 --- a/add_repo.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -# This script starts the discord bot of "L'Union des Rôlistes" - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -# TODO : Add commands verifications with $? (renvoie souvent 0 si tout se passe bien) -tmp='/usr/local/src' #'tmp/ur_bot/cogs' -ur_bot_dir='/usr/local/src/URbot' -cogs_folder="$ur_bot_dir/bot/cogs" -repo="$tmp/$1" -src="$repo/src" -a2=/etc/apache2 -www=/var/www/html - -# checks repo name has been supplied -if [ -z ${1+x} ]; then - echo 'error: argument not supplied' - echo - echo 'usage : ./add_repo.sh ' - exit -fi - -if [ ! -d "$repo" ] ; then - # downloads the repo from github.com - git clone "https://github.com/UnionRolistes/$1.git" "$repo" # TODO add several cogs at once - - # checks that the clone was successful - if [ $? != 0 ]; then - echo Failure - exit - fi -else - # updates the repo - cd "$repo" || exit - #git checkout . --> Dit qu'on est sur aucune branche. Problème, les branches n'ont pas toute une branche master (parfois main), donc on ne peut pas rajouter git pull origin master pour l'instant - git stash - git pull -fi - -# installs cogs (located in the src folder and starting with 'cog_') -echo ------------ TEXT: Installing cogs... ------------ -if [ ! -d $cogs_folder ] ; then - mkdir $cogs_folder -fi -find "$src" -maxdepth 1 -name "cog_*" -exec cp -vra '{}' $cogs_folder \; -echo - -# installs locale -if [ -d "$src/locale" ]; then - echo ------------ TEXT: Installing translations... ------------ - echo - cp -vra "$src/locale/." "$ur_bot_dir/locale" -fi - -echo ------------ TEXT: Installation complete. ------------ - -# installs www -if [ -d "$src/www" ]; then - if [ ! -d "$www/$1" ]; then - mkdir -v "$www/$1" - fi - cp -vra "$src/www/." "$www/$1" - chmod -R 775 "$www/$1" -fi - -# installs virtualhosts -#if [ -d "$src/sites-available" ]; then -# echo ------------ TEXT: Installing virtualhosts... ------------ -# cp -vra "$src/sites-available/." "$a2/sites-available" -# for f in "$src/sites-available/*.conf"; do -# ln -s $a2/sites-available/$f $a2/sites-enabled/$f -# a2ensite "$(basename "$f")" -# done -# systemctl reload apache2 -#fi - -# TODO bash 3 + -# TODO add installation of the cog's requirements.txt diff --git a/apache/ATTENTION!.txt b/apache/ATTENTION!.txt new file mode 100644 index 0000000..961a074 --- /dev/null +++ b/apache/ATTENTION!.txt @@ -0,0 +1,2 @@ +httpd.conf doit obligatoirement etre en `UTF-8`et line ending en `LF` (Unix) +sinon apache bug. (cat peut transformé l'encodage et les line ending) \ No newline at end of file diff --git a/apache/Dockerfile b/apache/Dockerfile new file mode 100644 index 0000000..aadf189 --- /dev/null +++ b/apache/Dockerfile @@ -0,0 +1,4 @@ +FROM php:8-apache + +RUN a2enmod proxy && \ + a2enmod proxy_http diff --git a/apache/default-httpd.conf b/apache/default-httpd.conf new file mode 100644 index 0000000..ae4b2c3 --- /dev/null +++ b/apache/default-httpd.conf @@ -0,0 +1,227 @@ +# This is the main Apache server configuration file. It contains the +# configuration directives that give the server its instructions. +# See http://httpd.apache.org/docs/2.4/ for detailed information about +# the directives and /usr/share/doc/apache2/README.Debian about Debian specific +# hints. +# +# +# Summary of how the Apache 2 configuration works in Debian: +# The Apache 2 web server configuration in Debian is quite different to +# upstream's suggested way to configure the web server. This is because Debian's +# default Apache2 installation attempts to make adding and removing modules, +# virtual hosts, and extra configuration directives as flexible as possible, in +# order to make automating the changes and administering the server as easy as +# possible. + +# It is split into several files forming the configuration hierarchy outlined +# below, all located in the /etc/apache2/ directory: +# +# /etc/apache2/ +# |-- apache2.conf +# | `-- ports.conf +# |-- mods-enabled +# | |-- *.load +# | `-- *.conf +# |-- conf-enabled +# | `-- *.conf +# `-- sites-enabled +# `-- *.conf +# +# +# * apache2.conf is the main configuration file (this file). It puts the pieces +# together by including all remaining configuration files when starting up the +# web server. +# +# * ports.conf is always included from the main configuration file. It is +# supposed to determine listening ports for incoming connections which can be +# customized anytime. +# +# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/ +# directories contain particular configuration snippets which manage modules, +# global configuration fragments, or virtual host configurations, +# respectively. +# +# They are activated by symlinking available configuration files from their +# respective *-available/ counterparts. These should be managed by using our +# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See +# their respective man pages for detailed information. +# +# * The binary is called apache2. Due to the use of environment variables, in +# the default configuration, apache2 needs to be started/stopped with +# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not +# work with the default configuration. + + +# Global configuration +# + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# NOTE! If you intend to place this on an NFS (or otherwise network) +# mounted filesystem then please read the Mutex documentation (available +# at ); +# you will save yourself a lot of trouble. +# +# Do NOT add a slash at the end of the directory path. +# +#ServerRoot "/etc/apache2" + +# +# The accept serialization lock file MUST BE STORED ON A LOCAL DISK. +# +#Mutex file:${APACHE_LOCK_DIR} default + +# +# The directory where shm and other runtime files will be stored. +# + +DefaultRuntimeDir ${APACHE_RUN_DIR} + +# +# PidFile: The file in which the server should record its process +# identification number when it starts. +# This needs to be set in /etc/apache2/envvars +# +PidFile ${APACHE_PID_FILE} + +# +# Timeout: The number of seconds before receives and sends time out. +# +Timeout 300 + +# +# KeepAlive: Whether or not to allow persistent connections (more than +# one request per connection). Set to "Off" to deactivate. +# +KeepAlive On + +# +# MaxKeepAliveRequests: The maximum number of requests to allow +# during a persistent connection. Set to 0 to allow an unlimited amount. +# We recommend you leave this number high, for maximum performance. +# +MaxKeepAliveRequests 100 + +# +# KeepAliveTimeout: Number of seconds to wait for the next request from the +# same client on the same connection. +# +KeepAliveTimeout 5 + + +# These need to be set in /etc/apache2/envvars +User ${APACHE_RUN_USER} +Group ${APACHE_RUN_GROUP} + +# +# HostnameLookups: Log the names of clients or just their IP addresses +# e.g., www.apache.org (on) or 204.62.129.132 (off). +# The default is off because it'd be overall better for the net if people +# had to knowingly turn this feature on, since enabling it means that +# each client request will result in AT LEAST one lookup request to the +# nameserver. +# +HostnameLookups Off + +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog ${APACHE_LOG_DIR}/error.log + +# +# LogLevel: Control the severity of messages logged to the error_log. +# Available values: trace8, ..., trace1, debug, info, notice, warn, +# error, crit, alert, emerg. +# It is also possible to configure the log level for particular modules, e.g. +# "LogLevel info ssl:warn" +# +LogLevel warn + +# Include module configuration: +IncludeOptional mods-enabled/*.load +IncludeOptional mods-enabled/*.conf + +# Include list of ports to listen on +Include ports.conf + + +# Sets the default security model of the Apache2 HTTPD server. It does +# not allow access to the root filesystem outside of /usr/share and /var/www. +# The former is used by web applications packaged in Debian, +# the latter may be used for local directories served by the web server. If +# your system is serving content from a sub-directory in /srv you must allow +# access here, or in any related virtual host. + + Options FollowSymLinks + AllowOverride None + Require all denied + + + + AllowOverride None + Require all granted + + + + Options Indexes FollowSymLinks + AllowOverride None + Require all granted + + +# +# Options Indexes FollowSymLinks +# AllowOverride None +# Require all granted +# + + + + +# AccessFileName: The name of the file to look for in each directory +# for additional configuration directives. See also the AllowOverride +# directive. +# +AccessFileName .htaccess + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + + +# +# The following directives define some format nicknames for use with +# a CustomLog directive. +# +# These deviate from the Common Log Format definitions in that they use %O +# (the actual bytes sent including headers) instead of %b (the size of the +# requested file), because the latter makes it impossible to detect partial +# requests. +# +# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended. +# Use mod_remoteip instead. +# +LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined +LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %O" common +LogFormat "%{Referer}i -> %U" referer +LogFormat "%{User-agent}i" agent + +# Include of directories ignores editors' and dpkg's backup files, +# see README.Debian for details. + +# Include generic snippets of statements +IncludeOptional conf-enabled/*.conf + +# Include the virtual host configurations: +IncludeOptional sites-enabled/*.conf + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/apache/vhost/000_api.conf b/apache/vhost/000_api.conf new file mode 100644 index 0000000..b75a848 --- /dev/null +++ b/apache/vhost/000_api.conf @@ -0,0 +1,13 @@ + + ServerName api.unionrolistes.fr + + ProxyRequests Off + + Order deny,allow + Allow from all + + + ProxyPass http://api:3000/ + ProxyPassReverse http://api:3000/ + + \ No newline at end of file diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..a9b362d --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.11 +WORKDIR /app +COPY requirements.txt requirements.txt +RUN pip3 install -r requirements.txt +EXPOSE 80 +COPY / ./ +CMD find . -name 'requirement*' -type f -exec pip3 install -r '{}' ';' ; ls -la ; uvicorn main:app --host 0.0.0.0 --port 3000 diff --git a/api/extends/base/_discord.py b/api/extends/base/_discord.py new file mode 100644 index 0000000..64b2585 --- /dev/null +++ b/api/extends/base/_discord.py @@ -0,0 +1,32 @@ +import discord +import asyncio +from dotenv import load_dotenv +import os + +tmp_discord_client = None + +# start discord client (doit etre deplacer dans api_base) + + +async def discord_client(): + global tmp_discord_client + if tmp_discord_client: + return tmp_discord_client + intents = discord.Intents.default() + tmp_discord_client = discord.Client(intents=intents) + load_dotenv() + TOKEN = os.getenv("DISCORD_TOKEN") + await tmp_discord_client.start(TOKEN, reconnect=True) + await tmp_discord_client.wait_until_ready() + return tmp_discord_client + + +async def get_discord_client(): + global tmp_discord_client + if tmp_discord_client: + return tmp_discord_client + tmp_discord_client = await discord_client() + return await tmp_discord_client + +asyncio.create_task(get_discord_client()) +# start discord client (doit etre deplacer dans api_base) diff --git a/api/extends/base/base.py b/api/extends/base/base.py new file mode 100644 index 0000000..ab6a15b --- /dev/null +++ b/api/extends/base/base.py @@ -0,0 +1,8 @@ +from fastapi import APIRouter + +router = APIRouter() + + +@router.get("/") +async def root(): + return {"message": "Hello from modular API!"} diff --git a/api/main.py b/api/main.py new file mode 100644 index 0000000..0d618e5 --- /dev/null +++ b/api/main.py @@ -0,0 +1,44 @@ +import asyncio +import traceback +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +import os +import importlib + +app = FastAPI() +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"] +) + + +def load_all_extensions(): + for dir in os.listdir("./extends"): + # run pip install -r requirements.txt if exists + if os.path.exists("./extends/" + dir + "/requirements.txt"): + try: + print("pip install -r ./extends/" + dir + "/requirements.txt") + os.system("pip install -r ./extends/" + dir + + "/requirements.txt") + except: + print("pip install -r ./extends/" + dir + + "/requirements.txt failed") + for file in os.listdir("./extends/" + dir): + if file.endswith(".py") and not file.startswith("_"): + try: + print(dir + "/" + file) + # dynamic import + tmp = importlib.import_module("extends." + dir + "." + + file[:-3]) + app.include_router(tmp.router) + except Exception as e: + print("Failed to load import {0}.".format(file)) + print(e) + print(''.join(traceback.format_exception(None, e, e.__traceback__))) + + +load_all_extensions() diff --git a/api/requirements.txt b/api/requirements.txt new file mode 100644 index 0000000..9d7d5b0 --- /dev/null +++ b/api/requirements.txt @@ -0,0 +1,4 @@ +fastapi==0.88.0 +uvicorn[standard]==0.20.0 +discord.py==2.1.0 +requests==2.28.1 \ No newline at end of file diff --git a/bot/.env.default b/bot/.env.default new file mode 100644 index 0000000..e6544fb --- /dev/null +++ b/bot/.env.default @@ -0,0 +1,3 @@ +# token for dev +DISCORD_TOKEN="--------------------------------------" +BOT_PREFIX="$" \ No newline at end of file diff --git a/bot/Dockerfile b/bot/Dockerfile new file mode 100644 index 0000000..16af888 --- /dev/null +++ b/bot/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.11 +WORKDIR /app +COPY /requirements.txt requirements.txt +RUN pip3 install -r requirements.txt +COPY ./ ./ +CMD find . -name 'requirement*' -type f -exec pip3 install -r '{}' ';' ; ls -la ; python -u UR-Bot.py diff --git a/bot/UR-Bot.py b/bot/UR-Bot.py new file mode 100644 index 0000000..681ddc2 --- /dev/null +++ b/bot/UR-Bot.py @@ -0,0 +1,72 @@ +# ext import +import discord +from dotenv import load_dotenv +# import DebugBot +from discord.ext import commands +import os +import asyncio + +# load .env file +load_dotenv() + +# get token from .env file +TOKEN = os.getenv('DISCORD_TOKEN') # get token from .env file +BOT_PREFIX = os.getenv('BOT_PREFIX') # get prefix from .env file + +# exit if no token found +if TOKEN is None: + print("The discord token is not defined \n\t defined it in the .env file (dev) \n\t or in the environment in docker-compose") + exit(1) + + +class BOT_BASE(commands.Bot): + async def on_ready(self): + print('--- We have successfully loggged in as {0.user}'.format(self)) + + async def on_message(self, message): + if message.author == self.user: + return + return await bot.process_commands(message) + + +# set listeners +intent = discord.Intents.default() +intent.members = True +intent.messages = True +intent.message_content = True # v2 + +bot = BOT_BASE(command_prefix=BOT_PREFIX, intents=intent, case_insensitive=True) # build bot + +groups = {} + +# laod all extensions in the glob "./**/*.py" +# like that to limit side effect between extension + + +async def load_all_extensions(): + for dir in os.listdir('./extends'): + # run pip install -r requirements.txt if exists + if os.path.exists('./extends/'+dir+'/requirements.txt'): + try: + print('pip install -r ./extends/'+dir+'/requirements.txt') + os.system('pip install -r ./extends/'+dir+'/requirements.txt') + except: + print('pip install -r ./extends/' + + dir+'/requirements.txt failed') + for file in os.listdir('./extends/'+dir): + if file.endswith('.py'): + try: + print(dir+'/'+file) + await bot.load_extension('extends.'+dir+'.'+file[:-3]) + except Exception as e: + print('Failed to load extension {0}.'.format(file)) + print(e) + + +# if the file is run directly, run the bot +if __name__ == '__main__': + # load all extensions + asyncio.run(load_all_extensions()) + + # run bot + bot.run(TOKEN) diff --git a/bot/extends/base/base.py b/bot/extends/base/base.py new file mode 100644 index 0000000..cd7bacd --- /dev/null +++ b/bot/extends/base/base.py @@ -0,0 +1,156 @@ +import os +import asyncio +from discord.ext import commands +from dotenv import load_dotenv + +load_dotenv() + +class Base(commands.Cog, name='Base'): + def __init__(self, bot: commands.Bot): + self.bot = bot + self._last_member = None + + # Chargement initial du Cog + async def cog_load(self): + print(f"{self.__class__.__name__} est chargée") + + # Commande de ping + @commands.command(name="ping", help='ping pong avec le bot', aliases=['pong', 'p']) + @commands.guild_only() + async def _ping(self, ctx): + await self._send_pong_response(ctx) + + # Commande d'affichage des crédits + @commands.command(name="credits", help='affiche les crédits', aliases=['credit', 'c']) + async def _credits(self, ctx): + credits = await self._get_credits() + if credits: + await ctx.send(credits) + else: + await ctx.send("Aucune information de crédits disponible.") + + # Commande d'affichage des versions + @commands.command(name="version", help='affiche la version du bot', aliases=['v']) + async def _version(self, ctx): + versions = await self._get_versions() + if versions: + await ctx.send(versions) + else: + await ctx.send("Aucune information de versions disponible.") + + # Commande d'aide + @commands.command(name="help", help='affiche les commandes, alias et description', aliases=['h', '?']) + async def _help(self, ctx): + help_msg = await self._generate_help_message() + await ctx.send(help_msg) + + # Envoie une réponse "Pong !" avec le temps de latence du bot + async def _send_pong_response(self, ctx): + latency = round(self.bot.latency, 3) * 1000 + await asyncio.gather( + ctx.message.add_reaction('🏓'), + ctx.send(f'Pong ! 🏓 {latency} ms') + ) + + # Récupère les informations de crédits depuis les fichiers + async def _get_credits(self): + credits = "" + parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + for directory in os.listdir(parent_dir): + credits_file_path = os.path.join(parent_dir, directory, 'credits.txt') + if os.path.exists(credits_file_path): + try: + with open(credits_file_path, 'r') as f: + credits += f.read() + '\n\n' + except Exception as e: + print(e) + if credits: + credits_lines = credits.splitlines() + formatted_credits = ( + f"```ansi\n" + f"\x1b[1;34m{credits_lines[0]}\x1b[0m\n" # Titre en bleu foncé + f"\x1b[1;32m{credits_lines[1]}\x1b[0m\n" # Ligne en vert clair + ) + for line in credits_lines[2:]: + formatted_credits += f"\x1b[1;36m{line}\x1b[0m\n" # Lignes en cyan clair + formatted_credits += "```" + return formatted_credits + else: + return None + + # Récupère les informations de versions depuis les fichiers + async def _get_versions(self): + versions = "" + parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + directory_names = { + 'base': 'Bot_Base', + 'prez': 'Bot_Presentation', + 'planning': 'Bot_Planning', + 'site': 'Web_Site' + } + for directory in directory_names: + version_file_path = os.path.join(parent_dir, directory, 'version.txt') + if os.path.exists(version_file_path): + try: + with open(version_file_path, 'r') as f: + version = f.read().strip() + formatted_version = ( + f"```ansi\n" + f"\x1b[1;34m{directory_names[directory]}\x1b[0m : \x1b[1;37mVersion \x1b[1;33m{version}\x1b[0m\n" + f"```" + ) + versions += formatted_version + except Exception as e: + print(e) + else: + formatted_version = ( + f"```ansi\n" + f"\x1b[1;34m{directory_names[directory]}\x1b[0m : \x1b[1;31mVersion introuvable\x1b[0m\n" + f"```" + ) + versions += formatted_version + if versions: + return versions + else: + return None + + # Génère un message d'aide avec les commandes triées par catégorie + async def _generate_help_message(self): + commands_by_category = self._get_commands_by_category() + help_msg = ( + f"```ansi\n" + f"\x1b[2;34;4mPréfixe\x1b[0m \x1b[2;31m{self.bot.command_prefix}\x1b[0m\n\n" + ) + for cat in commands_by_category: + category_commands = commands_by_category[cat] + command_list = self._get_command_list(category_commands) + help_msg += f"\x1b[2;34;4m{cat}\x1b[0m :\n{command_list}\n" + help_msg += "```" + return help_msg + + # Trie les commandes par catégorie + def _get_commands_by_category(self): + commands_by_category = {} + for command in self.bot.walk_commands(): + if command.cog_name not in commands_by_category: + commands_by_category[command.cog_name] = [] + commands_by_category[command.cog_name].append(command) + return dict(sorted(commands_by_category.items())) + + # Génère la liste de commandes pour une catégorie + def _get_command_list(self, commands): + command_list = "" + for command in commands: + aliases = self._get_command_aliases(command) + msg = f' -- \x1b[2;36m{command.help}\x1b[0m' if command.help is not None else '' + command_list += f"\x1b[2;33m{command.name}\x1b[0m{aliases}{msg}\n" + return command_list + + # Récupère les alias d'une commande + def _get_command_aliases(self, command): + return f'''{' ' + str(command.aliases).replace("'", "") if command.aliases != [] else ''}''' + +# Fonction d'initialisation du Cog +async def setup(bot): + bot.remove_command('help') + await bot.add_cog(Base(bot)) \ No newline at end of file diff --git a/bot/extends/base/credits.txt b/bot/extends/base/credits.txt new file mode 100644 index 0000000..4bce8a9 --- /dev/null +++ b/bot/extends/base/credits.txt @@ -0,0 +1,7 @@ +URBot_base Le bot discord de l'Union des Rôlistes + contributeurs : + - Mortifia#7249 + - Eὔδοξος#2170 + - Lyss#4053 + - Maestro#8364 + - Phrixus#7269 diff --git a/bot/extends/base/version.txt b/bot/extends/base/version.txt new file mode 100644 index 0000000..60a2d3e --- /dev/null +++ b/bot/extends/base/version.txt @@ -0,0 +1 @@ +0.4.0 \ No newline at end of file diff --git a/bot/requirements.txt b/bot/requirements.txt new file mode 100644 index 0000000..b5a3904 Binary files /dev/null and b/bot/requirements.txt differ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..841f43e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +version: '3' +name: union-des-rolistes + +services: + bot: + build: ${PWD}/bot #utilise le dockerfile pour cree le container a utiliser + container_name: bot_base + restart: always #redemarre le container si il s'eteint + env_file: + - ${PWD}/env/token.env + - ${PWD}/env/bot.env + volumes: + - ${PWD}/bot/extends/base:/app/extends/base #dossier ou est l'extension de la base + api: + build: ${PWD}/api #utilise le dockerfile pour cree le container a utiliser + container_name: api_base + ports: + - "3000:3000" + restart: always #redemarre le container si il s'eteint + environment: + - PYTHONUNBUFFERED=1 #get print of python + env_file: + - ${PWD}/env/token.env # get token + php: + image: php:8-apache + build: ${PWD}/apache #utilise le dockerfile pour cree le container a utiliser + container_name: php_base + volumes: + # - ./apache/default-httpd.conf:/etc/apache2/apache2.conf:ro # si besoin de modifier le fichier de conf apache (normalement pas besoin) + - ${PWD}/apache/vhost/000_api.conf:/etc/apache2/sites-enabled/000_api.conf:ro #fichier de conf apache pour l'api + ports: + - "80:80" + links: + - api + restart: always + depends_on: + # attend le lancement de ces containers avant de lancer le container + - bot + - api diff --git a/env/default.bot.env b/env/default.bot.env new file mode 100644 index 0000000..27eaee2 --- /dev/null +++ b/env/default.bot.env @@ -0,0 +1,2 @@ +BOT_PREFIX=$ # prefix pour les commandes +BOT_BASE_VERSION=x.x.x # version du bot (va sauter) \ No newline at end of file diff --git a/env/default.oauth.env b/env/default.oauth.env new file mode 100644 index 0000000..1b69f12 --- /dev/null +++ b/env/default.oauth.env @@ -0,0 +1,2 @@ +CLIENT_ID=xxxx +CLIENT_SECRET=xxxx \ No newline at end of file diff --git a/env/default.token.env b/env/default.token.env new file mode 100644 index 0000000..46c4519 --- /dev/null +++ b/env/default.token.env @@ -0,0 +1 @@ +DISCORD_TOKEN=xxxx #token pour comm avec discord \ No newline at end of file diff --git a/install.sh b/install.sh deleted file mode 100755 index 76774d7..0000000 --- a/install.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -# This script installs the discord bot of "L'Union des Rôlistes" - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -# Variables -install_folder="/usr/local/src/URbot" -src="src" -bot_pckg_name='bot' -bot_pckg="$src/$bot_pckg_name" -urpy_pckg="$src/urpy" -# TODO better variables - -python='python3.7' -venv='/opt/virtualenv/URBot' -bin="$venv/bin/" -service='Bot_Base.service' -requirements="$urpy_pckg/requirements.txt" - -# Installs required softwares -sudo apt update -sudo apt install -y $python -sudo apt install -y $python-venv -sudo apt install -y python3-venv -sudo apt install -y $python-dev -sudo apt install -y build-essential - -# Creates a python virtualenv -sudo $python -m venv $venv -source $bin/activate -sudo $bin/pip install -r "$requirements" -deactivate - -# Copies python code to install folder -sudo mkdir $install_folder -sudo cp -vra "$src/bot" $install_folder -sudo cp -vra "$src/start.py" $install_folder -sudo cp -vra "$src/locale" $install_folder -sudo cp -vra "$src/urpy" $venv/lib/$python/site-packages -# rush -sudo chmod -R 755 $install_folder -sudo chown "$USER" $install_folder - - -# Copies .service to /etc/systemd/system -sudo cp -v src/$service /etc/systemd/system -sudo systemctl enable $service - -echo - -# Reads and writes token into root folder -if [ ! -e $install_folder/.bot_token ]; then - echo '------------ TEXT: |~ Veuillez entrer le token du bot : ------------' - read -r bot_token - echo "$bot_token" | sudo tee $install_folder/.bot_token > /dev/null - echo - exit -fi -if [ -e $install_folder/.bot_token ]; then - echo '------------ TEXT: Token déjà saisi ------------' - echo - exit -fi - -echo '------------ TEXT: Creation des fichiers de stockage webhook ------------' -echo -# Create 2 files for webhook storing -if [ ! -e $install_folder/wh ]; then - touch $install_folder/wh - chmod 776 $install_folder/wh - exit -fi -if [ ! -e $install_folder/whPrez ]; then - touch $install_folder/whPrez - chmod 776 $install_folder/wh - exit -fi - -echo '------------ TEXT: Installation du bot terminée ------------' -echo - -echo '------------ TEXT: Begin webserver installation ------------' -echo - -apt install -y apache2 -apt install -y php -apt install -y libapache2-mod-php # TODO check if necessary -apt install -y php-xml -apt install -y php-curl -a2enmod cgid -systemctl restart apache2 - -# TODO add user name diff --git a/script/build_all.sh b/script/build_all.sh new file mode 100755 index 0000000..74af145 --- /dev/null +++ b/script/build_all.sh @@ -0,0 +1,4 @@ +# find all docker-compose.yml files with depth 3 add '-f' to each file stored in COMPOSE_FILES var +COMPOSE_FILES=`find ../ -maxdepth 3 -name docker-compose.yml -exec echo -f {} \;` +# echo $COMPOSE_FILES +docker-compose $COMPOSE_FILES config > compose-build.yml \ No newline at end of file diff --git a/script/config.sh b/script/config.sh new file mode 100755 index 0000000..51a213e --- /dev/null +++ b/script/config.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# run to env directory and execute this script to create env files and set values + +# for each file in the env directory +for file in *; do + # if file is a default.*.env file + if [[ $file == default.*.env ]]; then + # check if the file wihout the default exists + env_name=${file#default.} + env_name=${env_name%.env} + echo "---- $env_name.env ----" + # if it does not exist, create it + if [ ! -f $env_name.env ]; then + touch $env_name.env + fi + # for each line in the default file + while IFS=: read -r -u 9 line || [ -n "$line" ]; do # || [ -n "$line" ] est tres important sinon le dernier element ne sera pas lu + # trim start of line + line="${line#"${line%%[![:space:]]*}"}" + # if line is not empty and does not start with # + if [[ ! -z $line ]] && [[ $line != \#* ]]; then + + #get env variable name + env_var=${line%=*} + #get env variable value + env_value=${line#*=} + #remove comment if exist + env_value=${env_value%%#*} + # #if line has a comment get it + # if [[ $line == *#* ]]; then + # #get comment with comment symbol + # env_comment=\#${line#*#} + # else + # env_comment="" + # fi + + # if env_var exist in $env_name.env rewrite env_value with value in $env_name.env + # ps use actual value user as default valur + if grep -q "$env_var" $env_name.env; then + env_value=$(grep "$env_var" $env_name.env | cut -d '=' -f2) + env_value=${env_value%%#*} + fi + #ask user to change value of env variable + echo "Enter value for $env_var (default: $env_value):" + printf "" + read input + # if varname as character + if test ! -z "$input"; then + env_value=$input + fi + + #if env_var exist in $env_name.env rewrite it + if grep -q "$env_var" $env_name.env; then + sed -i "s/$env_var=.*/$env_var=$env_value/g" $env_name.env + else + #add line to file + echo "$env_var=$env_value" >> $env_name.env + fi + + + ##add line to file + #echo "$env_var=$env_value $env_comment" >> $env_name.env + #------------------------------------------------------------------------------------------------ + fi + done 9< $file + fi +done + + + # #example if, if else, else + # if [[ $file == default.*.env ]]; then + # env_name=${file#default.} + # env_name=${env_name%.env} + # touch $env_name.env + # cat $file >> $env_name.env + # elif [[ $file == *.env ]]; then + # env_name=${file%.env} + # touch $env_name.env + # cat $file >> $env_name.env + # else + # echo "File $file is not a valid env file" + # fi diff --git a/script/config_all.sh b/script/config_all.sh new file mode 100755 index 0000000..74b31c0 --- /dev/null +++ b/script/config_all.sh @@ -0,0 +1,11 @@ +cd .. +# for each directory in the current directory +for dir in *; do + # if env directory exist + if [ -d "$dir/env" ]; then + #run config.sh in env directory + cd $dir/env + ../../Bot_Base/script/config.sh + cd ../.. + fi +done \ No newline at end of file diff --git a/script/readme.md b/script/readme.md new file mode 100644 index 0000000..4708c95 --- /dev/null +++ b/script/readme.md @@ -0,0 +1,55 @@ +# script + +## config.sh + +il permet de mettre a jour tout les env sans avoir a tripatouiller les fichiers .env + +## config_all.sh + +il permet de mettre a jour tout les env sans avoir a tripatouiller les fichiers (met aussi a jour les env de toutes les extension).env + +## build_all.sh + +il construit tout le docker-compose avec la base et toutes les extensions + +## start + +lance le docker-compose \ +(il faut avoir construit le docker-compose avant) \ +(les services serotn temporairement inacessible moins de 10s) + +## usage + +```bash + # pwd = /xxxxxxxxxxxxx/union_des_rolistes/Bot_Base + ./config_all.sh + ./build_all.sh + ./start.sh +``` +## clone bot and plug-in +```bash +cd Bot-Base +./script/config_all.sh +./script/build_all.sh +./script/start.sh +./update.sh (normalemnt pas besoin) +... +``` +## installation et paramétrage de Docker et WSL + +pour windows: +installer wsl -> https://learn.microsoft.com/fr-fr/windows/wsl/install +installer docker -> https://docs.docker.com/engine/install/ + +pour linux: +installer docker -> https://docs.docker.com/engine/install/ubuntu/ +liste des commandes: +1-sudo apt-get install docker.io +2-sudo systemctl +3-start docker +4-sudo usermod -aG docker your_username +5-docker version +6-mkdir dossier +7-cd dossier +8-git clone lien-site_ +9-docker-compose -f docker-compose.yml ../Bot_Planning_python/bot/docker-compose.yml config > conf-build-docker-compose.yml \ No newline at end of file diff --git a/script/start.sh b/script/start.sh new file mode 100755 index 0000000..94ad2a4 --- /dev/null +++ b/script/start.sh @@ -0,0 +1,2 @@ +# cd .. +docker-compose -f compose-build.yml up -d --build --force-recreate --remove-orphans \ No newline at end of file diff --git a/src/Bot_Base.service b/src/Bot_Base.service deleted file mode 100755 index b5df668..0000000 --- a/src/Bot_Base.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Discord Bot for unionrolistes.fr -RequiresMountsFor=/usr/local/src/ -After=multi-user.target - -[Service] -Type=simple -ExecStart=/usr/local/src/URbot/start.py -Restart=always -RestartSec=5s -StandardOutput=journal -StandardError=inherit - -[Install] -WantedBy=multi-user.target \ No newline at end of file diff --git a/src/bot/URbot.py b/src/bot/URbot.py deleted file mode 100755 index e87c3b7..0000000 --- a/src/bot/URbot.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/opt/virtualenv/URBot/bin/python - -import inspect -import logging -import os -import platform -import sys -import importlib -from importlib import resources - -from discord.ext import commands - -from urpy import MyHelpCommand -from urpy.utils import error_log, code_block, log -from bot import _, strings -from bot import localization - -import urpy - -debug = platform.system() == 'Windows' - -from bot import info -from bot import settings -from bot.cog_General import General -from bot.cog_About import About - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - - -class URBot(urpy.MyBot): - """ - Discord bot for "l'Union des Rôlistes". Contains global settings - and functions. - - Additional groups of functions can be added at runtime through - the .add_cog method. - """ - - def __init__(self): - """ - Creates an instance of URBot. Use the run method to start it. - """ - self.localization = localization # TODO move localization to urpy - super(URBot, self).__init__(settings.command_prefix, help_command=MyHelpCommand(self.localization)) - self.cog_general = General(self) - - # adds base cogs to the bot - self.add_cog(self.cog_general) - self.add_cog(About(self)) - - self.isDebugMode = debug - - @staticmethod - def get_credits(): - """ Return creditted people. """ - return resources.read_text(info, 'credits.txt') - - @staticmethod - def get_version(): - """ Return version number. """ - return resources.read_text(info, 'version.txt') - - @staticmethod - def get_name(): - """ Return title of the bot.""" - return _(strings.bot_title) - - async def on_ready(self): - """ Listener to the on_ready event. """ - error_log("We have logged in as {}!".format(self.user)) - - async def invoke(self, ctx: commands.Context): - self.localization.set_current_user(ctx.author.id) - await super(URBot, self).invoke(ctx) - - async def on_command_error(self, context, exception: commands.CommandError): - """ Listener to the on_command_error event. """ # TODO better docstring - if isinstance(exception, commands.UserInputError): - await context.send(_("{err_msg}\nIncorrect usage ☹ Check help of the command for more information.").format( - err_msg=code_block(exception))) - else: - raise exception - - def add_to_command(self, command: str, *callbacks): - """ - Add one or several callbacks to a cog_General discord command. - - @param command str - name of the command (ex: 'edit') - @callbacks callbacks iterator[functions] - callbacls - """ - self.cog_general.add_to_command(command, *callbacks) - - -if debug: - cogs_path = os.path.abspath('cogs') - token_path = '../../../bot_token' -else: - cogs_path = '/usr/local/src/URbot/bot/cogs' - token_path = '/usr/local/src/URbot/.bot_token' - - -def main(): - logging.basicConfig(level=logging.INFO) - ur_bot = URBot() - log("Loading cogs...") - # adds the "cogs" folder to the import path - sys.path.append(cogs_path) - - if os.path.exists(cogs_path): - # scans the "cogs" folder for cogs to add to the bot - for dir_entry in os.scandir(cogs_path): - dir_entry: os.DirEntry - - # imports and adds all found cogs - if dir_entry.is_dir() and dir_entry.name != '__pycache__' and not dir_entry.name.startswith('.'): - - # tries to import the cog module - try: - module = importlib.import_module(f"{dir_entry.name}.cog") - - except ValueError as e: # TODO fix error handling - error_log( - f"The package \'{dir_entry.name}\' does not contain a module named \'cog.py\' (in {dir_entry.path}).") - - else: - # retrieves all discord.Cog based classes - cog_classes = filter(lambda member: inspect.isclass(member[1]) and issubclass(member[1], commands.Cog), - inspect.getmembers(module)) - for Cog in cog_classes: - # adds cog to the bot - cog = Cog[1](ur_bot) - ur_bot.add_cog(cog) - log(f"Loaded : {cog.qualified_name}") - log("Done") - else: - log("No cogs found") - - # reads the bot token - with open(token_path) as f: - bot_token = f.read() - - # starts the bot - ur_bot.run(bot_token) - - -if __name__ == '__main__': - main() diff --git a/src/bot/__init__.py b/src/bot/__init__.py deleted file mode 100755 index a78b127..0000000 --- a/src/bot/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -import gettext - -from urpy import Localization - -import platform - -if platform.system() == 'Windows': - localedir = '../locale' -else: - localedir = '/usr/local/bin/URbot/locale' - -localization = Localization() -domain = 'bot_base' -# TODO automate adding all languages -localization.set_localedir(localedir) -localization.add_translation('bot_base', ['fr']) -localization.add_translation('bot_base', ['en']) -localization.add_translation('bot_base', ['special-rp', 'fr']) - - -_ = localization.gettext \ No newline at end of file diff --git a/src/bot/cog_About.py b/src/bot/cog_About.py deleted file mode 100644 index d7f6b77..0000000 --- a/src/bot/cog_About.py +++ /dev/null @@ -1,47 +0,0 @@ -from discord.ext import commands -from bot import templates -from bot import _, strings -import urpy -from urpy.utils import * - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -class About(commands.Cog): - """ This cog contains commands used to get general information about the bot. """ - __doc__ = strings.About_descr - - def __init__(self, owner: urpy.MyBot): - """ Creates an about cog. """ - super(About, self).__init__() - self.bot = owner - - @commands.command(brief=strings.version_brief, help=strings.version_help) - async def version(self, ctx: commands.Context): - """ Displays the version numbers. """ - await self.send_info_msg(ctx) - - @commands.command(brief=strings.credit_brief, help=strings.credit_help) - async def credit(self, ctx: commands.Context): - """ Displays the credits. """ - await self.send_info_msg(ctx, with_credits=True) - - async def send_info_msg(self, ctx, with_credits=False): - """ Sends a message containing the names, version numbers [and credits] of all the services. """ - # generates the descriptions for all the subservices of the bot - services = "\n\n".join( - formatted_template(templates, 'service_template.txt', - name=cog.get_name(), - version=cog.get_version(), - credits=cog.get_credits() if with_credits else "") - - for name, cog in self.bot.cogs.items() if isinstance(cog, urpy.MyCog) - ) - - # sends the message - await ctx.send(code_block(formatted_template(templates, 'version_template.txt', - version=self.bot.get_version(), - name=self.bot.get_name(), - services=services, - credits=self.bot.get_credits() if with_credits else ""))) diff --git a/src/bot/cog_General.py b/src/bot/cog_General.py deleted file mode 100644 index 1e684f6..0000000 --- a/src/bot/cog_General.py +++ /dev/null @@ -1,54 +0,0 @@ -from discord.ext import commands -import bot -from bot import localization, _, strings -import urpy - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - - -class General(commands.Cog): - __doc__ = strings.General_descr - - def __init__(self, URBot: urpy.MyBot): - self.bot = URBot - self.callbacks = { - 'edit': [], - 'done': [], - 'cancel': [] - } - - async def call_callbacks(self, command: str, ctx: commands.Context): - for callback in self.callbacks[command]: - await callback(ctx) - - @commands.command(brief=strings.edit_brief, help=strings.edit_help) - async def edit(self, ctx): - """ Call callbacks bound to the edit command. """ - await self.call_callbacks('edit', ctx) - - @commands.command(brief=strings.done_brief, help=strings.done_help) - async def done(self, ctx): - """ Call callbacks bound to the done command. """ - await self.call_callbacks('done', ctx) - - @commands.command(brief=strings.cancel_brief) - async def cancel(self, ctx): - """ Call callbacks bound to the cancel command. """ - await self.call_callbacks('cancel', ctx) - - @commands.command(brief=strings.lang_brief, help=strings.lang_help) - async def lang(self, ctx: commands.Context, language): - """ Switches to specified language """ - if language in localization.languages: - localization.set_user_language(language) - await ctx.send(_("Your language has successfully been set to english !")) - - else: - await ctx.send(_("Sorry, i don't know this language !")) - - def add_to_command(self, command: str, *callbacks): - """ Adds a callback to the specified command. It will be called on command invokation.""" - for callback in callbacks: - self.callbacks[command].append(callback) diff --git a/src/bot/info/__init__.py b/src/bot/info/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/src/bot/info/credits.txt b/src/bot/info/credits.txt deleted file mode 100755 index 2746973..0000000 --- a/src/bot/info/credits.txt +++ /dev/null @@ -1,2 +0,0 @@ -Lyss -Maestro#8364 \ No newline at end of file diff --git a/src/bot/info/version.txt b/src/bot/info/version.txt deleted file mode 100755 index a2268e2..0000000 --- a/src/bot/info/version.txt +++ /dev/null @@ -1 +0,0 @@ -0.3.1 \ No newline at end of file diff --git a/src/bot/settings.py b/src/bot/settings.py deleted file mode 100644 index 7c9c702..0000000 --- a/src/bot/settings.py +++ /dev/null @@ -1 +0,0 @@ -command_prefix = '$' \ No newline at end of file diff --git a/src/bot/strings.py b/src/bot/strings.py deleted file mode 100644 index 3c2c804..0000000 --- a/src/bot/strings.py +++ /dev/null @@ -1,25 +0,0 @@ -from urpy.localization import lcl - -bot_title = lcl('URbot - The discord bot of "l\'Union des Rôlistes"') -lang_brief = lcl('Switches to specified language') -lang_help = lcl( - """\ -Switches to specified language - -Available languages : - - en - - fr - - special-rp\ -""") -done_brief = lcl('Confirms the current action') -done_help = lang_brief -edit_brief = lcl('Edits a message') -edit_help = edit_brief -cancel_brief = lcl('Cancels the current action') -cancel_help = cancel_brief -version_brief = lcl('Displays the version numbers') -version_help = version_brief -credit_brief = lcl('Displays the credits') -credit_help = credit_brief -About_descr = lcl('This category groups various commands to display general information about the bot.') -General_descr = lcl('This category groups various commands whose utility depends on the context.') diff --git a/src/bot/templates/__init__.py b/src/bot/templates/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/bot/templates/credit_template.txt b/src/bot/templates/credit_template.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/bot/templates/service_template.txt b/src/bot/templates/service_template.txt deleted file mode 100644 index a8b5d7c..0000000 --- a/src/bot/templates/service_template.txt +++ /dev/null @@ -1,4 +0,0 @@ - {name} - ------ - -> version : {version} - {credits} \ No newline at end of file diff --git a/src/bot/templates/version_template.txt b/src/bot/templates/version_template.txt deleted file mode 100644 index 0b29378..0000000 --- a/src/bot/templates/version_template.txt +++ /dev/null @@ -1,6 +0,0 @@ -{name} -====== - -> Version : {version} - {credits} - -{services} \ No newline at end of file diff --git a/src/locale/_pot/bot_base.pot b/src/locale/_pot/bot_base.pot deleted file mode 100644 index b19fa95..0000000 --- a/src/locale/_pot/bot_base.pot +++ /dev/null @@ -1,23 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2021-07-22 22:55+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=cp1252\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" - - -#: bot\URbot.py:61 -msgid "bot_title" -msgstr "" - -#: bot\URbot.py:70 -msgid \ No newline at end of file diff --git a/src/locale/en/LC_MESSAGES/bot_base.mo b/src/locale/en/LC_MESSAGES/bot_base.mo deleted file mode 100644 index e4d70bf..0000000 Binary files a/src/locale/en/LC_MESSAGES/bot_base.mo and /dev/null differ diff --git a/src/locale/en/LC_MESSAGES/bot_base.po b/src/locale/en/LC_MESSAGES/bot_base.po deleted file mode 100644 index 31a8bbf..0000000 --- a/src/locale/en/LC_MESSAGES/bot_base.po +++ /dev/null @@ -1,50 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2021-07-22 21:19+0200\n" -"PO-Revision-Date: 2021-07-22 21:41+0200\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 3.0\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"Last-Translator: \n" -"Language: en\n" - -#: bot\URbot.py:61 -msgid "bot_title" -msgstr "URbot - The discord bot of \"l'Union des Rôlistes\"" - -#: bot\cog_About.py:9 -msgid "About_descr" -msgstr "This category groups various commands to display general information about the bot." - -#: bot\cog_About.py:16 -msgid "version_descr" -msgstr "Displays the version numbers" - -#: bot\cog_About.py:21 -msgid "credit_descr" -msgstr "Displays the credits" - -#: bot\cog_General.py:6 -msgid "General_descr" -msgstr "This category groups various commands whose utility depends on the context." - -#: bot\cog_General.py:20 -msgid "edit_descr" -msgstr "Edits a message" - -#: bot\cog_General.py:25 -msgid "done_descr" -msgstr "Confirms the current action" - -#: bot\cog_General.py:30 -msgid "cancel_descr" -msgstr "Cancels the current action" diff --git a/src/locale/fr/LC_MESSAGES/bot_base.mo b/src/locale/fr/LC_MESSAGES/bot_base.mo deleted file mode 100644 index 175f5bd..0000000 Binary files a/src/locale/fr/LC_MESSAGES/bot_base.mo and /dev/null differ diff --git a/src/locale/fr/LC_MESSAGES/bot_base.po b/src/locale/fr/LC_MESSAGES/bot_base.po deleted file mode 100644 index a9a8eba..0000000 --- a/src/locale/fr/LC_MESSAGES/bot_base.po +++ /dev/null @@ -1,173 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR ORGANIZATION -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2021-07-27 06:08+0200\n" -"PO-Revision-Date: 2021-07-27 06:08+0200\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: fr_FR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: pygettext.py 1.5\n" -"X-Generator: Poedit 3.0\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Poedit-Basepath: ../../..\n" -"X-Poedit-KeywordsList: lcl\n" -"X-Poedit-SearchPath-0: bot\n" -"X-Poedit-SearchPath-1: urpy\n" -"X-Poedit-SearchPathExcluded-0: bot/cogs\n" - -#: bot/URbot.py:77 -#, python-brace-format -msgid "" -"{err_msg}\n" -"Incorrect usage ☹ Check help of the command for more information." -msgstr "" -"{err_msg}\n" -"Utilisation incorrecte ☹ Allez voir l'aide de la commande pour plus " -"d'information." - -#: bot/cog_General.py:42 -msgid "Your language has successfully been set to english !" -msgstr "Votre langue a bien été passée en français !" - -#: bot/cog_General.py:45 -msgid "Sorry, i don't know this language !" -msgstr "Désolé, je ne connais pas cette langue !" - -#: bot/strings.py:3 -msgid "URbot - The discord bot of \"l'Union des Rôlistes\"" -msgstr "URBot - Le bot discord de l'Union des Rôlistes" - -#: bot/strings.py:4 -msgid "Switches to specified language" -msgstr "Change la langue de l'utilisateur" - -#: bot/strings.py:6 -msgid "" -"Switches to specified language\n" -"\n" -"Available languages :\n" -" - en\n" -" - fr\n" -" - special-rp" -msgstr "" -"Change la langue de l'utilisateur\n" -"\n" -"Langues disponibles :\n" -" - en\n" -" - fr\n" -" - special-rp" - -#: bot/strings.py:14 -msgid "Confirms the current action" -msgstr "Confirme l'action en cours" - -#: bot/strings.py:16 -msgid "Edits a message" -msgstr "Édite un message" - -#: bot/strings.py:18 -msgid "Cancels the current action" -msgstr "Annule l'action en cours" - -#: bot/strings.py:20 -msgid "Displays the version numbers" -msgstr "Affiche les numéros de version" - -#: bot/strings.py:22 -msgid "Displays the credits" -msgstr "Affiche les crédits" - -#: bot/strings.py:24 -msgid "" -"This category groups various commands to display general information about " -"the bot." -msgstr "" -"Cette catégorie comporte des commandes donnant des informations générales " -"sur le bot." - -#: bot/strings.py:25 -msgid "" -"This category groups various commands whose utility depends on the context." -msgstr "" -"Cette catégorie regroupe des commandes générales qui jouent un rôle " -"différent en fonction du contexte." - -#: urpy/help.py:12 -msgid "Shows this message" -msgstr "Affiche ce message" - -#: urpy/help.py:13 -msgid "Commands:" -msgstr "Commandes:" - -#: urpy/help.py:14 -msgid "No Category" -msgstr "" - -#: urpy/help.py:46 -#, python-brace-format -msgid "" -"Type {0}{1} command for more info on a command.\n" -"You can also type {0}{1} category for more info on a category." -msgstr "" -"Entrez {0}{1} commande pour plus d'info sur une commande.\n" -"Vous pouvez aussi entrer {0}{1} catégorie pour plus d'info sur une catégorie." - -#~ msgid "Error: Webhook not supplied." -#~ msgstr "Erreur : Webhook non fourni." - -#~ msgid "Other" -#~ msgstr "Sans Catégorie" - -#~ msgid "version_descr" -#~ msgstr "Affiche les numéros de version" - -#~ msgid "credit_descr" -#~ msgstr "Affiche les crédits" - -#~ msgid "About_descr" -#~ msgstr "" -#~ "Cette catégorie comporte des commandes donnant des informations générales " -#~ "sur le bot." - -#~ msgid "General_descr" -#~ msgstr "" -#~ "Cette catégorie regroupe des commandes générales qui jouent un rôle " -#~ "différent en fonction du contexte." - -#~ msgid "bot_title" -#~ msgstr "URBot - Le bot discord de l'Union des Rôlistes" - -#~ msgid "edit_descr" -#~ msgstr "Édite un message" - -#~ msgid "done_descr" -#~ msgstr "Confirme l'action en cours" - -#~ msgid "cancel_descr" -#~ msgstr "Annule l'action en cours" - -#, fuzzy -#~| msgid "credit_descr" -#~ msgid "credits.txt" -#~ msgstr "Affiche les crédits" - -#, fuzzy -#~| msgid "cancel_descr" -#~ msgid "cancel" -#~ msgstr "Annule l'action en cours" - -#, fuzzy -#~| msgid "Switches to specified language" -#~ msgid " Switches to specified language " -#~ msgstr "Change la langue de l'utilisateur" - -#~ msgid "Incorrect usage. Check 'help lang' for more information." -#~ msgstr "Utilisation incorrecte ☹ Allez voir l'aide en tapant '$help lang'." diff --git a/src/locale/special-rp/LC_MESSAGES/bot_base.mo b/src/locale/special-rp/LC_MESSAGES/bot_base.mo deleted file mode 100644 index 4708499..0000000 Binary files a/src/locale/special-rp/LC_MESSAGES/bot_base.mo and /dev/null differ diff --git a/src/locale/special-rp/LC_MESSAGES/bot_base.po b/src/locale/special-rp/LC_MESSAGES/bot_base.po deleted file mode 100644 index faeec26..0000000 --- a/src/locale/special-rp/LC_MESSAGES/bot_base.po +++ /dev/null @@ -1,96 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: \n" -"POT-Creation-Date: 2021-07-23 04:21+0200\n" -"PO-Revision-Date: 2021-07-23 05:09+0200\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.0\n" -"X-Poedit-Basepath: ../../..\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Poedit-KeywordsList: lcl\n" -"X-Poedit-SearchPath-0: bot\n" -"X-Poedit-SearchPath-1: urpy\n" - -#: bot/URbot.py:81 -#, python-brace-format -msgid "" -"{err_msg}\n" -"Incorrect usage ☹ Check help of the command for more information." -msgstr "" -"{err_msg}\n" -"Ben alors, on ne sait plus comment utiliser cette commande Voyageur ? ☹ " -"Consultez votre manuel si vous requérez assistance." - -# 🪶 is a feather. -#: bot/cog_General.py:42 -msgid "Your language has successfully been set to english !" -msgstr "Bienvenue dans le chemin de Traverse ! 🪶" - -#: bot/cog_General.py:45 -msgid "Sorry, i don't know this language !" -msgstr "Mmm, non. Désolé ! Ce dialecte m'est inconnu." - -#: bot/strings.py:3 -msgid "URbot - The discord bot of \"l'Union des Rôlistes\"" -msgstr "" - -#: bot/strings.py:4 -msgid "Switches to specified language" -msgstr "Portail de téléportation" - -#: bot/strings.py:6 -msgid "Confirms the current action" -msgstr "Prends une décision avec assurance" - -#: bot/strings.py:8 -msgid "Edits a message" -msgstr "Direction le scribble" - -#: bot/strings.py:10 -msgid "Cancels the current action" -msgstr "Retourne sur ses pas en plein désarroi" - -#: bot/strings.py:12 -msgid "Displays the version numbers" -msgstr "Affiche les dates de publication des différentes sections" - -#: bot/strings.py:14 -msgid "Displays the credits" -msgstr "Affiche les auteurs de ce manuel" - -#: bot/strings.py:16 -msgid "" -"This category groups various commands to display general information about " -"the bot." -msgstr "" - -#: bot/strings.py:17 -msgid "" -"This category groups various commands whose utility depends on the context." -msgstr "" - -#: urpy/classes/help.py:12 -msgid "Shows this message" -msgstr "Affiche le manuel du Voyageur" - -#: urpy/classes/help.py:13 -msgid "Commands:" -msgstr "" - -#: urpy/classes/help.py:14 -msgid "No Category" -msgstr "" - -#: urpy/classes/help.py:46 -#, python-brace-format -msgid "" -"Type {0}{1} command for more info on a command.\n" -"You can also type {0}{1} category for more info on a category." -msgstr "" -"~ {0}{1} commande ~\n" -"Bonne route Voyageur. Que la déesse veille sur vous." diff --git a/src/start.py b/src/start.py deleted file mode 100644 index b303b77..0000000 --- a/src/start.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/opt/virtualenv/URBot/bin/python -from bot.URbot import main - -if __name__ == '__main__': - main() diff --git a/src/urpy/__init__.py b/src/urpy/__init__.py deleted file mode 100644 index 6c3e23b..0000000 --- a/src/urpy/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from urpy.localization import Localization, lcl -from urpy.help import MyHelpCommand -from urpy.my_commands import MyBot, MyCog, MyContext -from urpy.get_ressources import * - -base_localization = Localization('../locale') # TODO path for linux -_ = base_localization.gettext diff --git a/src/urpy/get_ressources.py b/src/urpy/get_ressources.py deleted file mode 100644 index 82d18be..0000000 --- a/src/urpy/get_ressources.py +++ /dev/null @@ -1,4 +0,0 @@ -from importlib import resources - -def get_planning_anncmnt_mdl() -> str: - return resources.read_text('urpy.templates', "planning_annoucement_template.txt") diff --git a/src/urpy/help.py b/src/urpy/help.py deleted file mode 100644 index 4f17ef1..0000000 --- a/src/urpy/help.py +++ /dev/null @@ -1,82 +0,0 @@ -import discord -from discord.ext import commands - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -from urpy.localization import lcl - -_ = lcl - - -class MyHelpCommand(commands.DefaultHelpCommand): - def __init__(self, localization, **options): - super().__init__( - help=lcl('Shows this message'), - commands_heading=lcl('Commands:'), - no_category=lcl('No Category'), **options) # TODO 'No Category' in french - global _ - # This check is necessary cause HelpCommand is deep copied every time in discord api. """ - if _ is lcl: - _ = localization.gettext - - def add_command_formatting(self, command): - """A utility function to format the non-indented block of commands and groups. - - Parameters - ------------ - command: :class:`Command` - The command to format. - """ - - if command.description: - self.paginator.add_line(_(command.description), empty=True) - - signature = self.get_command_signature(command) - self.paginator.add_line(signature, empty=True) - domain = getattr(command.cog, 'domain', None) - if command.help: - try: - self.paginator.add_line(_(command.help, domain), empty=True) - except RuntimeError: - for line in command.help.splitlines(): - self.paginator.add_line(line) # TODO localization here - self.paginator.add_line() - - def get_ending_note(self): - """:class:`str`: Returns help command's ending note. This is mainly useful to override for i18n purposes.""" - command_name = self.invoked_with - return _("Type {0}{1} command for more info on a command.\n" - "You can also type {0}{1} category for more info on a category.").format(self.clean_prefix, - command_name) - - def add_indented_commands(self, commands, *, heading, max_size=None): - if not commands: - return - if heading.startswith('\u200b'): - heading = _(heading[1:-1]) + ':' - self.paginator.add_line(_(heading[:-1]) + heading[-1]) - max_size = max_size or self.get_max_size(commands) - - get_width = discord.utils._string_width - for command in commands: - domain = getattr(command.cog, 'domain', None) - name = command.name - width = max_size - (get_width(name) - len(name)) - entry = '{0}{1:<{width}} {2}'.format(self.indent * ' ', name, _(command.short_doc, domain), width=width) - self.paginator.add_line(self.shorten_text(entry)) - - async def send_cog_help(self, cog): - domain = getattr(cog, 'domain', None) - if cog.description: - self.paginator.add_line(_(cog.description, domain), empty=True) - filtered = await self.filter_commands(cog.get_commands(), sort=self.sort_commands) - self.add_indented_commands(filtered, heading=_(self.commands_heading, domain)) - - note = self.get_ending_note() - if note: - self.paginator.add_line() - self.paginator.add_line(note) - - await self.send_pages() diff --git a/src/urpy/localization.py b/src/urpy/localization.py deleted file mode 100644 index 424fdab..0000000 --- a/src/urpy/localization.py +++ /dev/null @@ -1,84 +0,0 @@ -import gettext - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -def lcl(s: str, domain=None): - """ Marks a string for localization. """ - return s - - -class Localization: # TODO default localedir - def __init__(self, localedir='', default_language='fr', default_domain='bot_base'): - self._localedir = localedir - self.languages = {} # TODO make languages a class - self._default_language = default_language - self.users_custom_language = {} - self._current_user_id = '' - self._default_domain = default_domain - self._current_domain = None - # TODO add handling of several domains (context manager) - # TODO autoload - - def add_translation(self, domain, codes, *aliases): # TODO make aliases - language = gettext.translation(domain, self._localedir, codes, fallback=True) - if codes[0] not in self.languages: - self.languages[codes[0]] = {} - if 'en' not in self.languages: - self.languages['en'] = {} - - self.languages[codes[0]][domain] = language.gettext - if domain not in self.languages['en']: - self.add_translation(domain, ['en']) - - def set_default_language(self, lang_code): - if lang_code in self.languages: - self._default_language = lang_code - return True - else: - return False - - def set_user_language(self, lang_code): - if lang_code in self.languages: - if lang_code == self._default_language: - if self._current_user_id in self.users_custom_language: - del self.users_custom_language[self._current_user_id] - else: - self.users_custom_language[self._current_user_id] = lang_code - return True - else: - return False - - def set_current_user(self, user_id): - self._current_user_id = user_id - - def set_current_domain(self, domain): - self._current_domain = domain - - def gettext(self, s, domain=None): - if not s: - return "" - - if domain is None: - if self._current_domain is not None: - domain = self._current_domain - else: - domain = self._default_domain - - if self._current_user_id in self.users_custom_language: - lang = self.users_custom_language[self._current_user_id] - else: - lang = self._default_language - # TODO automatize fallback based on folder name - if lang in self.languages: - lang = self._default_language if domain not in self.languages[lang] else lang # TODO optimize all this - if domain in self.languages[lang]: - return self.languages[lang][domain](s) - else: - return s - else: - return s - - def set_localedir(self, param): - self._localedir = param diff --git a/src/urpy/my_commands.py b/src/urpy/my_commands.py deleted file mode 100644 index 586f9be..0000000 --- a/src/urpy/my_commands.py +++ /dev/null @@ -1,120 +0,0 @@ -from functools import partial -from types import MethodType - -import discord -from discord.ext import commands -from importlib import resources -from abc import ABC, abstractmethod, ABCMeta - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -class VersionNCreditInterface(ABC): - @staticmethod - @abstractmethod - def get_credits(): - """ Return credits. """ - pass - - @staticmethod - @abstractmethod - def get_version() -> str: - """ Return version number.""" - pass - - @staticmethod - @abstractmethod - def get_name() -> str: - """ Return name.""" - pass - - -class MyBot(commands.Bot, VersionNCreditInterface): - @abstractmethod - def __init__(self, command_prefix='$', *args, **kwargs): - super(MyBot, self).__init__(command_prefix=command_prefix, *args, **kwargs) - -class MyCogMeta(type(commands.Cog), VersionNCreditInterface, ABCMeta): - pass - -# TODO: shaky code, needs to be cleaned -class MyCog(commands.Cog, VersionNCreditInterface, metaclass=MyCogMeta): - def __init__(self, bot, domain): - self.bot = bot - self.domain = domain - - @commands.Cog.listener() - async def on_ready(self): - print(f"\t| {self.qualified_name} started.") - -# TODO: à améliorer -from functools import wraps - - -# def add_to_comm(name): -# def decorator(method): -# @wraps(method) -# def _impl(self, *method_args, **method_kwargs): -# print(str(method)) -# return _impl -# -# return decorator - - - # args[0].bot.add_to_command(name, partial(func, args[0])) -# -# class Test: -# def __init__(self, name): -# self.name = name -# -# @add_to_comm("non") -# def test(self): -# print("doggo") -# -# @add_to_comm("yes") -# def toost(self): -# print("cat") -# -# t = Test("Alpha") -# # t.test() -# # t.toost() - -class MyContext(commands.Context): - def __init__(self, ctx: commands.Context, delete_after=None): - """ - Creates a Context whose messages sent are deleted by default. - - @author Lyss - @mail - @date 28/06/21 - - Parameters - ---------- - ctx : context to copy - """ - super().__init__(**ctx.__dict__) - self.delete_after = delete_after - - async def send(self, content=None, **kwargs): - """ - Override Context.send to delete messages by default. - - @author Lyss - @mail - @date 28/06/21 - - Parameters - ---------- - content - kwargs - - Returns - ------- - - """ - if 'delete_after' not in kwargs: - kwargs['delete_after'] = self.delete_after - - await self.message.delete(delay=kwargs['delete_after']) - await super().send(content, **kwargs) diff --git a/src/urpy/requirements.txt b/src/urpy/requirements.txt deleted file mode 100644 index 9826c61..0000000 --- a/src/urpy/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -discord -requests -lxml \ No newline at end of file diff --git a/src/urpy/templates/__init__.py b/src/urpy/templates/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/urpy/templates/planning_annoucement_template.txt b/src/urpy/templates/planning_annoucement_template.txt deleted file mode 100644 index 106fdfe..0000000 --- a/src/urpy/templates/planning_annoucement_template.txt +++ /dev/null @@ -1,14 +0,0 @@ - ** Nouveau jeu de rôle ! ** - - **Type ** {type} -:calendar: ** Date ** {date} -:clapper: **Titre** {title} -:timer: ** Durée moyenne du scénario ** {length} -:crown: **MJ** {pseudoMJ} -:d10: ** Système** {system} -:baby::skin-tone-1: **PJ Mineur ** {minors_allowed} -:star2: ** Plateformes ** {platforms} -:grey_question: ** Détails** -{details} - -** Participe ** ✅ / ** Ne participe pas ❌ ** \ No newline at end of file diff --git a/src/urpy/utils.py b/src/urpy/utils.py deleted file mode 100644 index 5ddc76d..0000000 --- a/src/urpy/utils.py +++ /dev/null @@ -1,121 +0,0 @@ -import re -import sys -import requests -import discord -from importlib import resources -from urpy import _ - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -def error_log(*msg, name="BOT"): - print(f"{name}:ERROR|", *msg, file=sys.stderr) - - -async def get_public_ip() -> str: - """ - Return public IP. - - @author Lyss - @mail - @date 28/06/21 - - - Returns - ------- - str - IP address. - """ - return requests.get('https://api.ipify.org').text - -async def get_informations(msg: discord.Message): - """ - Extract information from an announcement message. - - @author Lyss - @mail - @date 28/06/21 - - Parameters - ---------- - msg : str - Announcement message. - - Returns - ------- - dict[str, str] - A dict linking an information name to its value. - Ex: " ** Type ** One Shoot " becomes {'type': 'One Shoot'} - """ - infos = {} - - # Matches strings of the form : ' ** {name} ** {value} ' ending on ':', '**' or '\n' - for match in re.finditer("\*\*(.*)\*\* *(?:\n| )(.*)\n(?::|\*\*|\n)", msg.embeds[0].description): - infos[match.group(1).strip().lower()] = match.group(2) - return infos - - -def code_block(s): - return f"```{s}```" - - -def edit_fmt(s): - return f"\|~ {s} ~|" - - -def code_line(s: str): - return f"`{s}`" - - -def formatted_template(template_pckg, template_name, **kwargs): - res = "" - size_last_line = 0 - with resources.open_text(template_pckg, template_name) as f: - for line in f: - # regex match to analyze the line -> the goal is to identify chars that indicate the position of - # an underline such as === and --- (the ---- form doesn't accept anything after it, otherwise - # it is not considered as an underline) - match = re.match('([ \t]*)(?:(-+)([ \t\n]*$)|(=*)((?:({.*})|.)*))', line, flags=re.DOTALL | re.MULTILINE) - new_line = match.group(1) - - # case of a --- underline - if match.group(2): - new_line += match.group(2)[0] * size_last_line - new_line += match.group(3) - else: - # case of a === underline - if match.group(4): - new_line += match.group(4)[0] * size_last_line - # formats text that doesn't symbolize an underline - new_line += match.group(5).format(**kwargs) - - size_last_line = len(new_line.strip()) - - if size_last_line or (not size_last_line and not match.group(6)): - res += new_line - - if res.endswith('\n'): - return res[:-1] - else: - return res - - -def log(*msgs, name='BOT'): - print(f"{name}|", *msgs, file=sys.stderr) - - -def html_header_content_type(*msgs): - print("Content-Type: text/html") - print() - print(*msgs, sep='\n') - - -def html_header_relocate(dest: str): - print("Status: 303 See other") - print(f"Location: {dest}") - print() - - -def html_header_webhook_not_supplied(): - html_header_content_type('Error: Webhook not supplied.') diff --git a/src/urpy/xml.py b/src/urpy/xml.py deleted file mode 100644 index 10d0e6d..0000000 --- a/src/urpy/xml.py +++ /dev/null @@ -1,175 +0,0 @@ -import pickle -from pathlib import Path - -import discord -from discord import Webhook, AsyncWebhookAdapter -from aiohttp import ClientSession -from lxml import etree as et -import cgi -from urpy.utils import error_log, log -from urpy.localization import lcl, Localization -import re -from datetime import datetime - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - - -game_tag = 'partie' -title_tag = 'titre' -max_players_tag = 'capacite' -min_players_tag = 'minimum' -nb_joined_tag = 'inscrits' -date_tag = 'date' -time_tag = 'heure' -length_tag = 'duree' -type_tag = 'type' -mj_tag = 'mj' -system_tag = 'systeme' -minors_allowed_tag = 'pjMineur' -platforms_tag = 'plateformes' -details_tag = 'details' -link_tag = 'lien' - -tags = [title_tag, max_players_tag, min_players_tag, nb_joined_tag, - date_tag, time_tag, length_tag, type_tag, mj_tag, system_tag, - minors_allowed_tag, platforms_tag, details_tag, link_tag] - -tags_to_form = { - title_tag: 'jdr_title', - max_players_tag: 'maxJoueurs', - min_players_tag: 'minJoueurs', - #date_tag: 'jdr_date', car on ne veut pas que celui là s'écrive automatiquement. On veut d'abord séparer la date et l'heure et faire le mettre sous la forme Y-M-D - length_tag: 'jdr_length', - type_tag: 'jdr_type', - system_tag: 'jdr_system', - minors_allowed_tag: 'jdr_pj', - details_tag: 'jdr_details', -} - -tags_to_lambda = { - nb_joined_tag: lambda f: '0', - #time_tag: lambda f: '15h00', - mj_tag: lambda f: f"<@{f.getvalue('user_id')}> [{f.getvalue('pseudo')}]", - platforms_tag: lambda f: " ".join(f.getlist('platform')), - link_tag: lambda f: 'https://discord.com/channels/TODO' -} - -_ = lcl - - -class Calendar: - """ - This class allows updating an xml file that contains the data of an event calendar. - """ - creators_to_webhook = {} - - def __init__(self, fp: str, localization: Localization = None): # TODO localization - """ - Create an xmlCalendar. - - @fp path to xml file - """ - self.fp = fp - import os - from urpy import utils - #utils.html_header_content_type() - #print(os.listdir("/usr/share/urbot/")) - #print(open("/usr/share")) - self.tree: et.ElementTree = et.parse(self.fp, et.XMLParser(remove_blank_text=True)) - if localization is not None: - global _ - _ = localization.gettext - - def get_last_id(self) -> int: # TODO change name and more - root = self.tree.getroot() - - if 'last_id' in root.attrib: - return int(root.get('last_id')) - else: - last_id = self.find_last_id() - root.set('last_id', str(last_id)) - return last_id - - def find_last_id(self) -> int: - return max(map(lambda e: int(e.attrib['id']), self.tree.getroot())) - # TODO check Publish - - async def add_event(self, form: cgi.FieldStorage, embed: discord.Embed): - """ Add an event to the calendar. """ - - print('Debug: Chargement du webhook...') - with open(f'/usr/local/src/URbot/wh', 'rb') as f: # TODO clean up - d = pickle.load(f) - print('Debug: Webhook chargé !') - - wh_url, guild_id, channel_id = d[int(form.getvalue('user_id'))] - - async with ClientSession() as client: - webhook: Webhook = Webhook.from_url(wh_url, adapter=AsyncWebhookAdapter(client)) - - msg = await webhook.send("", wait=True, embed=embed, allowed_mentions=discord.AllowedMentions(users=True)) - - try: - root = self.tree.getroot() - root.set('last_id', str(int(root.get('last_id')) + 1)) - parent = et.SubElement(self.tree.getroot(), game_tag, id=root.get('last_id')) - - for tag in tags: - new_elmnt = et.SubElement(parent, tag) - if tag in tags_to_form: - new_elmnt.text = form.getvalue(tags_to_form[tag], 'NotFound') - elif tag == link_tag: - new_elmnt.text = f"https://discord.com/channels/{guild_id}/{channel_id}/{msg.id}" - elif tag == date_tag: - - date_string = form.getvalue(tags_to_form[date_tag]) #On récupére la date en string (actuellement sous la forme 10/08/2021 11:00) - date = datetime.strptime(date_string, "%d/%m/%Y %H:%M") #On transforme ce string en objet (Doit avoir la même mise en forme / / / : que le string cité ci-dessus) - date = date.strftime("%Y-%m-%d")#On récupère uniquement la date sous la forme 2021-08-10, pour la compatibilité dans le calendrier web - #Ces changements de format ne concernent pas le message Discord, déjà posté, mais l'écriture dans le xml. Le calendrier php a besoin d'une date et heure sous ce format pour fonctionner - - new_elmnt.text = date - elif tag == time_tag: - - date_string = form.getvalue(tags_to_form[date_tag]) #On récupére la date en string (actuellement sous la forme 10/08/2021 11:00) - date2 = datetime.strptime(date_string, "%d/%m/%Y %H:%M") #On transforme ce string en objet (Doit avoir la même mise en forme / / / : que le string cité ci-dessus) - heure = date2.strftime("%Hh%M") #On récupère uniquement l'heure, sous la forme 12h00 - new_elmnt.text = heure - else: - new_elmnt.text = tags_to_lambda[tag](form) - except Exception as e: - print("Problème lors de l'écriture dans le XML") #Si l'écriture dans le xml ne marche pas, il ne faut pas que cela empêche de poster le message sur Discord - - def remove_event(self, id, show_errors=True): # TODO better name for show_errors - root = self.tree.getroot() - - try: - root.remove(next(e for e in root if e.get('id') == str(id))) - except StopIteration: - if show_errors: - error_log(f"Attempt to remove an event that doesn't exist. Event id : {id}") - else: - log(f"Event with id {id} successfully removed.") - - def remove_events(self, ids: str): - """ - - :param ids: - """ - - groups = ids.split(" ") - - for group in groups: - if group.isnumeric(): - self.remove_event(group) - elif re.match("^[0-9]*-[0-9]*$", group): - start, end = (int(id) for id in group.split('-')) - assert start <= end - for id in range(start, end): - self.remove_event(id, show_errors=False) - else: - raise ValueError("Incorrect format of the ids' string.") - - def save(self): - self.tree.write(self.fp, pretty_print=True) diff --git a/src/www/css/master.css b/src/www/css/master.css deleted file mode 100644 index 7dfede1..0000000 --- a/src/www/css/master.css +++ /dev/null @@ -1,37 +0,0 @@ - - -/*Police et taille d'écriture : */ -html { - /* 1 */ - font-size: 16px; - font-weight: normal; - line-height: 1.5; - /* 2 */ - -webkit-text-size-adjust: 100%; - /* 3 */ - color: white; -} -body{ -padding: 20px; -overflow: auto; -background-color: #23272A; -} -.titleCenter{ /*!IMPORTANT, utilisé dans plusieurs pages*/ -text-align: center; -} -.divCenter{ - margin: 0 auto; -} - - -/*Cadre : */ -#UR { - padding: 1.2em; - width: 85%; /*Taille horizontale du formulaire*/ - margin-left: 7%; - border : 1px solid #000; - box-shadow: 5px 8px 6px black; - background: #2C2F33; -} - -a{ text-decoration: none; } \ No newline at end of file diff --git a/src/www/img/ccby.png b/src/www/img/ccby.png deleted file mode 100644 index 6c37b6f..0000000 Binary files a/src/www/img/ccby.png and /dev/null differ diff --git a/src/www/img/ur-bl2.png b/src/www/img/ur-bl2.png deleted file mode 100644 index 4ae7416..0000000 Binary files a/src/www/img/ur-bl2.png and /dev/null differ diff --git a/src/www/index.html b/src/www/index.html deleted file mode 100644 index 1c766c3..0000000 --- a/src/www/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - L'Union des Rolistes - - - - - - - -
-

Ce site est actuellement en maintenance

-

Veuillez nous excuser pour la gêne occasionnée

- -
Union des Rôlistes
-
- - - - \ No newline at end of file diff --git a/start.sh b/start.sh deleted file mode 100755 index e67be02..0000000 --- a/start.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# This script starts the discord bot of "L'Union des Rôlistes" - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -# start / restart the service -echo "Starting..." -sudo systemctl restart Bot_Base - -# wait a little to find out if the bot was successfully started -sleep 1 - -# check SubState -sub_state=$(systemctl show -p SubState Bot_Base --value) - -if [ "$sub_state" = "running" ]; then - echo "Success!" -else - echo "Failure... (use 'journalctl -eu Bot_Base' to check the log.)" -fi \ No newline at end of file diff --git a/update.ps1 b/update.ps1 new file mode 100644 index 0000000..1bc9cd7 --- /dev/null +++ b/update.ps1 @@ -0,0 +1,18 @@ +# Set the current directory to the parent directory +Set-Location .. + +# Find all docker-compose.yml files in subdirectories with a depth of 3 or less +$files = Get-ChildItem -Path . -Filter docker-compose.yml -Recurse -Depth 3 + +# for each file found, add "-f $file.x" to the tmp variable +$tmp = $files | ForEach-Object { " -f $($_.FullName)" } + +# Set the current directory to the Bot_Base directory +Set-Location Bot_Base + +# Use docker-compose to generate a new docker-compose file based on the files found +& docker-compose $tmp config > "conf-build-docker-compose.yml" + + +# Use docker-compose to restart all containers in the stack defined in the new docker-compose file +& docker-compose -f conf-build-docker-compose.yml up -d --remove-orphans --force-recreate --build \ No newline at end of file diff --git a/update.sh b/update.sh new file mode 100644 index 0000000..1a147a5 --- /dev/null +++ b/update.sh @@ -0,0 +1,11 @@ +#!/bin/bash +cd .. +#all docker-compose depth 3 +tmp="" +find . -maxdepth 3 -name "docker-compose.yml" |while read i; do + tmp=$tmp + " -f " + $i +done +cd Bot_Base +docker-compose $tmp config > conf-build-docker-compose.yml +#docker-desktop force restart of all containers of the stack +docker-compose -f conf-build-docker-compose.yml up -d --remove-orphans --force-recreate --build diff --git a/updateBot.sh b/updateBot.sh deleted file mode 100644 index 00a3685..0000000 --- a/updateBot.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# This script updates the files for the discord bot of "L'Union des Rôlistes", and restart it - -#UR_Bot © 2020 by "Association Union des Rôlistes & co" is licensed under Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA) -#To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ -#Ask a derogation at Contact.unionrolistes@gmail.com - -cd /usr/local/src/Bot_Base -git pull #Pour mettre à jour le script add_repo.sh -bash add_repo.sh Bot_Base -bash install.sh -bash add_repo.sh Bot_Planning_python -bash add_repo.sh Web_Planning -bash add_repo.sh Web_Presentation -bash add_repo.sh Bot_Presentation - -#Droits particuliers : -chmod 776 /var/www/html/Web_Planning/Calendar/data/events.xml - -service apache2 restart -bash start.sh \ No newline at end of file