dece 9 months ago
parent c6326d5ee0
commit e6c3edcdbd

@ -19,3 +19,4 @@ scaruffi = "==0.0.3"
wolframalpha = "*"
meteofrance-api = "~=1.0.2"
openai = "~=0.25.0"
apscheduler = "~=3.9.0"

933
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

@ -69,7 +69,7 @@
"commands": ["doupsland"]
},
"gpt3": {
"openai_key": ""
"openai_key": "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",
"join_lines": "; ",
"computing_replies": ["Hmm…"]
},
@ -176,6 +176,11 @@
"wakeup_messages": ["/me wakes up"],
"snore_rate": 1.0
},
"shrlok": {
"socket_path": "/tmp/shrlok.sock",
"file_root": "/tmp",
"url_root": "http://localhost/"
},
"taxref": {
"commands": ["taxref", "scientifize"],
"not_found_reply": "Not found!",
@ -203,7 +208,7 @@
"aliases": {
"wolfram": ["wolframalpha", "compute"]
},
"api_key": "",
"api_key": "URTWTW-3KHWL4VV8W",
"max_pods": 1
},
"yell": {
@ -213,7 +218,7 @@
},
"youtube": {
"commands": ["youtube"],
"api_key": ""
"api_key": "AIzaSyCSyKdjGxcfjcj7FmgQRlWXF7ARpX8TC80"
}
}
}

@ -1,3 +1,4 @@
import asyncio
import importlib
import json
import os
@ -9,13 +10,15 @@ from pathlib import Path
from typing import Any, Iterable, Optional
import irc.client
import irc.client_aio
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from irc.client import Connection, Event, NickMask
from edmond.log import Logger
from edmond.plugin import Plugin
class Bot(irc.client.SimpleIRCClient, Logger):
class Bot(irc.client_aio.AioSimpleIRCClient, Logger):
"""Main class for the IRC bot: handles connection and manages plugins."""
CHANNELS_RUNTIME_KEY = "_channels"
@ -27,7 +30,9 @@ class Bot(irc.client.SimpleIRCClient, Logger):
self.plugins: list[Plugin] = []
self.values: dict[str, Any] = {}
self.storage: dict[str, Any] = self.get_storage()
self.tasks: list[asyncio.Task] = []
self.done: bool = False
self.scheduler = AsyncIOScheduler()
@property
def nick(self) -> str:
@ -72,6 +77,11 @@ class Bot(irc.client.SimpleIRCClient, Logger):
except OSError as exc:
self.log_e(f"Could not save storage file: {exc}")
def handle_task(self, coro):
"""Schedule a task in the event loop. Keep a reference to cancel it."""
task = self.connection.reactor.loop.create_task(coro)
self.tasks.append(task)
def on_welcome(self, connection: Connection, event: Event):
"""Handle a successful connection to a server."""
self.log_i(f"Connected to server {event.source}.")
@ -84,8 +94,14 @@ class Bot(irc.client.SimpleIRCClient, Logger):
if event.source.nick == self.nick:
self.log_i(f"Joined {event.target}.")
self.channels.append(event.target)
self.scheduler.add_job(self.flubiz, 'cron', hour='1',
minute='52')
self.scheduler.start()
self.run_plugin_callbacks(event)
async def flubiz(self):
self.say('#idi0crates', "acab")
def on_part(self, connection: Connection, event: Event):
"""Handle someone, possibly the bot, leaving a channel."""
if event.source.nick == self.nick:
@ -118,11 +134,14 @@ class Bot(irc.client.SimpleIRCClient, Logger):
"""Connect the bot to server, join channels and start responding."""
self.log_i("Starting Edmond.")
self.load_plugins()
self.log_i("Connecting to server.")
self.connect(self.config["host"], self.config["port"], self.nick)
self.log_i("Connecting to server")
signal.signal(signal.SIGTERM, self.handle_sigterm)
try:
self.connect(self.config["host"], self.config["port"], self.nick)
self.start()
except irc.client.ServerConnectionError as exc:
self.log_c(f"Connection failed: {exc}")
except KeyboardInterrupt:
self.log_i("Caught keyboard interrupt.")
except Exception as exc:
@ -135,7 +154,7 @@ class Bot(irc.client.SimpleIRCClient, Logger):
def load_plugins(self):
"""Load all installed plugins."""
self.log_i("Loading plugins.")
self.log_i("Loading plugins")
plugin_files = os.listdir(Path(__file__).parent / "plugins")
plugin_names = map(
lambda f: os.path.splitext(f)[0],
@ -199,7 +218,13 @@ class Bot(irc.client.SimpleIRCClient, Logger):
if self.done:
return
self.log_i("Stopping Edmond.")
self.save_storage()
self.save_storage() # FIRST THINGS FIRST
for task in self.tasks:
if not task.cancelled():
self.log_d(f"Cancelling task {task.get_name()}")
task.cancel()
if self.connection.is_connected():
self.connection.close()
self.reactor.loop.close()
self.done = True

Loading…
Cancel
Save