ircrobots/ircrobots/bot.py

63 lines
2.2 KiB
Python
Raw Normal View History

2020-04-01 14:36:53 +00:00
import asyncio, inspect
import anyio
from queue import Queue
from typing import Any, Awaitable, Callable, cast, Dict, List, Tuple
from irctokens import Line
from .server import ConnectionParams, Server
RECONNECT_DELAY = 10.0 # ten seconds reconnect
class Bot(object):
def __init__(self):
self.servers: Dict[str, Server] = {}
self._server_queue: asyncio.Queue[Server] = asyncio.Queue()
# methods designed to be overridden
def create_server(self, name: str):
return Server(name)
async def disconnected(self, server: Server):
await asyncio.sleep(RECONNECT_DELAY)
await self.add_server(server.name, server.params)
async def line_read(self, server: Server, line: Line):
pass
async def line_send(self, server: Server, line: Line):
pass
async def add_server(self, name: str, params: ConnectionParams) -> Server:
server = self.create_server(name)
self.servers[name] = server
await server.connect(params)
await self._server_queue.put(server)
return server
async def _run_server(self, server: Server):
async with anyio.create_task_group() as tg:
async def _read():
while not tg.cancel_scope.cancel_called:
lines = await server._read_lines()
for line in lines:
await self.line_read(server, line)
await tg.cancel_scope.cancel()
async def _write():
try:
while not tg.cancel_scope.cancel_called:
lines = await server._write_lines()
for line in lines:
await self.line_send(server, line)
except Exception as e:
print(e)
await tg.cancel_scope.cancel()
await tg.spawn(_read)
await tg.spawn(_write)
del self.servers[server.name]
await self.disconnected(server)
async def run(self):
async with anyio.create_task_group() as tg:
while not tg.cancel_scope.cancel_called:
server = await self._server_queue.get()
await tg.spawn(self._run_server, server)