mutubot/main.py
2024-11-07 19:37:12 +01:00

173 lines
5.1 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import discord
import yaml
import requests
from datetime import date
import urllib.parse
# To send discord messages (fucking async functions…)
import asyncio
from apscheduler.schedulers.background import BackgroundScheduler
scheduler = BackgroundScheduler()
scheduler.start()
from dotenv import load_dotenv
load_dotenv()
from email.message import EmailMessage
import smtplib, ssl
# Create a secure SSL context
ssl_context = ssl.create_default_context()
def load_guilds_data():
with open("guilds.yml", 'r') as stream:
try:
return yaml.safe_load(stream)
except yaml.YAMLError as exc:
print(exc)
def send_mail(guild, subject, content):
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = guild['mail_from']
msg['To'] = guild['mailing']
msg.set_content(content)
with smtplib.SMTP_SSL(guild['smtp_host'], guild['smtp_port'], context=ssl_context) as server:
server.login(guild['smtp_username'], guild['smtp_pass'])
server.send_message(msg)
def mail_message(message):
send_mail(guilds[message.guild.id], f'Nouveau message discord de {message.author.display_name}', f'{message.author.display_name}:\n{message.content}')
def req(url, data):
x = requests.post(url, headers={'Content-Type': 'application/x-www-form-urlencoded'}, data=data)
if x.status_code != 200:
print('ERROR', x)
print(x.content)
raise Exception('Request error ' + str(x.status_code))
# Load some data
TOKEN = os.getenv('DISCORD_TOKEN')
guilds = load_guilds_data()
reminder_channels = []
for i in guilds:
if 'reminder_channel' in guilds[i]:
reminder_channels.append(guilds[i]['reminder_channel'])
from html.parser import HTMLParser
class TokenFinder(HTMLParser):
def __init__(self):
self.token=None
super().__init__()
def handle_starttag(self, tag, attrs_tuple):
if tag != 'input':
return
attrs = dict(attrs_tuple)
if tag == 'input' and 'type' in attrs and attrs['type'] == 'hidden' and 'name' in attrs and attrs['name'] == 'control' and 'value' in attrs:
self.token = attrs['value']
def create_framavote (guild, names):
erase_framadate(guild['framavote'])
for i in range(len(guild['members'])):
create_line_framadate(guild['framavote'], 'AnneONyme'+str(i), names)
def erase_framadate (admin_url):
req(admin_url, 'remove_all_votes=')
req(admin_url, 'confirm_remove_all_votes=')
def create_line_framadate (admin_url, voter, names):
finder = TokenFinder()
finder.feed(requests.get(admin_url).content.decode('UTF-8'))
if not finder.token:
print('Framavote token not found')
data = 'control=' + finder.token + '&name=' + voter + ''.join('&choices%5B'+str(i)+'%5D=+' for i in range(len(names))) + '&save='
print(data)
x = req(admin_url, data)
@scheduler.scheduled_job('cron', day=25)
def cleaner ():
for guild_id in guilds:
erase_framadate(guilds[guild_id]['framadate_week'])
erase_framadate(guilds[guild_id]['framadate_weekend'])
# TODO erase calc revenus ?
@scheduler.scheduled_job('cron', day=1)
def reminder ():
for i in guilds:
print(f"reminding {i} : {guilds[i]['mailing']}")
message = generate_reminder_message(guilds[i])
send_mail(guilds[i], 'La mutunion cest bientôt !', message)
channel = client.get_channel(guilds[i]['reminder_channel'])
asyncio.run_coroutine_threadsafe(channel.send(message), client.loop)
def generate_reminder_message (guild):
# If the 10 is weekend
sondage = guild['framadate_week']
if date.today().replace(day=10).weekday() > 4:
sondage = guild['framadate_weekend']
return f"""
Coucou !
Il est lheure de déclarer ses revenus :
<{guild['link_declaration']}>
Et dannoncer à quelle heure vous souhaitez faire la mutunion :
<{sondage}>
Bon début de mois :D
Le mutubot
"""
# Discord API
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
randomvote = None
@client.event
async def on_ready():
print(f'{client.user} is connected to the following guild:\n')
for guild in client.guilds:
print(f'{guild.name} (id: {guild.id})')
@client.event
async def on_message(message):
global randomvote
if message.author == client.user:
return
if message.guild.id not in guilds:
return
if message.content.startswith('!randomvote '):
await message.reply('Êtes vous sûr·e ? Répondez « Pamplemousse agrivoltaiste » pour confirmer')
randomvote = message.content.split(' ')[1:]
return
if message.content == 'Pamplemousse agrivoltaiste' and message.type == discord.MessageType.reply :
create_framavote(guilds[message.guild.id], ['1', '2', '3', '4', '5', '6'])
randomvote = None
await message.reply("Cest fait ! Vérifiez bien par vous même parce que je suis un peu fini à larache…")
return
if message.channel.id in guilds[message.guild.id]['mailed_channels']:
mail_message(message)
# Actually starts the bot
client.run(TOKEN)