InfoBot/infobot.py
2024-07-18 16:51:09 +02:00

125 lines
4.5 KiB
Python

import slixmpp
import asyncio
import aiosqlite
from slixmpp.exceptions import IqError, IqTimeout
class InfoBot(slixmpp.ClientXMPP):
def __init__(self, jid, password, mucs):
super().__init__(jid, password)
self.mucs = mucs # Lista dei MUC da joinare
self.add_event_handler("session_start", self.start)
self.add_event_handler("groupchat_message", self.muc_message)
self.add_event_handler("disconnected", self.reconnect)
self.loop = asyncio.get_event_loop()
self.loop.run_until_complete(self.initialize_db())
async def initialize_db(self):
self.db = await aiosqlite.connect("infobot.db")
await self.db.execute(
"CREATE TABLE IF NOT EXISTS infos (name TEXT PRIMARY KEY, content TEXT, counter INTEGER DEFAULT 0)"
)
await self.db.commit()
async def add_info(self, name, content):
await self.db.execute(
"INSERT OR REPLACE INTO infos (name, content, counter) VALUES (?, ?, COALESCE((SELECT counter FROM infos WHERE name = ?), 0))",
(name, content, name),
)
await self.db.commit()
async def delete_info(self, name):
await self.db.execute(
"DELETE FROM infos WHERE name = ?", (name,)
)
await self.db.commit()
async def get_info(self, name):
cursor = await self.db.execute(
"SELECT content, counter FROM infos WHERE name = ?", (name,)
)
row = await cursor.fetchone()
if row:
content, counter = row
await self.db.execute(
"UPDATE infos SET counter = ? WHERE name = ?", (counter + 1, name)
)
await self.db.commit()
return content
return None
async def get_top_infos(self):
cursor = await self.db.execute(
"SELECT name, counter FROM infos ORDER BY counter DESC LIMIT 10"
)
rows = await cursor.fetchall()
return rows
async def start(self, event):
self.send_presence()
await self.get_roster()
# Unirsi ai MUC
for muc in self.mucs:
self.join_muc(muc)
def join_muc(self, muc):
room, nick = muc
self.plugin['xep_0045'].join_muc(room, nick)
def muc_message(self, msg):
body = msg['body']
if body.startswith("%"):
command, *params = body[1:].split(maxsplit=1)
if command == "add" and len(params) == 1:
try:
name, content = params[0].split(" ", 1)
name, content = name.strip(), content.strip()
self.loop.create_task(self.add_info(name, content))
msg.reply(f"Fattoide '{name}' aggiunto.").send()
except ValueError:
msg.reply("Uso corretto: !add <nome> <descrizione>").send()
elif command == "del" and len(params) == 1:
name = params[0].strip()
self.loop.create_task(self.delete_info(name))
msg.reply(f"Fattoide '{name}' cancellato.").send()
elif command == "top":
self.loop.create_task(self.handle_top_infos(msg))
else:
self.loop.create_task(self.handle_get_info(msg, command))
async def handle_get_info(self, msg, command):
info = await self.get_info(command)
if info:
msg.reply(info).send()
else:
msg.reply(f"Nessun fattoide trovato per '{command}'.").send()
async def handle_top_infos(self, msg):
top_infos = await self.get_top_infos()
if top_infos:
response = "\n".join([f"{name}: {counter}" for name, counter in top_infos])
msg.reply(f"Top 10 fattoidi:\n{response}").send()
else:
msg.reply("Nessun fattoide disponibile.").send()
async def reconnect(self, event):
# Riconnettersi al server
print("Tentativo di riconnessione...")
await asyncio.sleep(5) # Attendere 5 secondi prima di riconnettersi
self.connect()
self.process(forever=False)
if __name__ == "__main__":
jid = "infobot@example.tld"
password = "sekret"
mucs = [
("lozibaldone@conference.xmpp-it.net", "infobot"),
("bots@chat.woodpeckersnest.space", "infobot"),
("xmpp-it@conference.xmpp-it.net", "infobot")
]
xmpp = InfoBot(jid, password, mucs)
xmpp.register_plugin('xep_0045') # Plugin per MUC
xmpp.connect()
xmpp.process(forever=False)