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 ").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)