93 lines
2.4 KiB
Python
93 lines
2.4 KiB
Python
"""
|
|
v5 (GLaDOS)
|
|
===========
|
|
|
|
Description
|
|
-----------
|
|
Manage the V5 layer of GLaDOS.
|
|
"""
|
|
|
|
import logging
|
|
import socket
|
|
from threading import Thread
|
|
from functools import wraps
|
|
|
|
|
|
class V5:
|
|
"""Manage connexion beetween the bot and the V5 server, and manage callbacks.
|
|
|
|
Attributes
|
|
----------
|
|
irc : irc.IRC, public
|
|
An IRC instance.
|
|
|
|
sock : ssl.SSLSocket, private
|
|
The V5 socket.
|
|
handler : Thread, private
|
|
callbacks : list, private
|
|
List of the registred callbacks.
|
|
|
|
Methods
|
|
-------
|
|
start : NoneType, public
|
|
Start v5 handler.
|
|
on : function, public
|
|
Add a callback to the v5 handler.
|
|
|
|
handle : NoneType, private
|
|
Handle the incoming messages and callbacks.
|
|
"""
|
|
|
|
def __init__(self, v5_params: tuple, irc):
|
|
"""Initialize V5 handle.
|
|
|
|
Parameters
|
|
----------
|
|
v5 : tuple
|
|
The information on V5 server (host, port).
|
|
irc : irc.IRC
|
|
An initialized IRC instance.
|
|
"""
|
|
self.irc = irc
|
|
self.__sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
|
self.__sock.bind(v5_params)
|
|
self.__handler = Thread(target=self.__handle)
|
|
self.__callbacks = []
|
|
|
|
def start(self):
|
|
"""Start v5 handler."""
|
|
self.__handler.start()
|
|
logging.info("started")
|
|
|
|
def on(self, event):
|
|
"""Adds a callback to the v5 handler.
|
|
|
|
Parameters
|
|
----------
|
|
event : function
|
|
``event`` is a function taking in parameter a list of channels and a string, and return
|
|
``True`` if the callback should be executed.
|
|
"""
|
|
def callback(func):
|
|
@wraps(func)
|
|
def wrapper(channels, message):
|
|
func(channels, message)
|
|
self.__callbacks.append((event, wrapper))
|
|
return wrapper
|
|
|
|
return callback
|
|
|
|
def __handle(self):
|
|
"""Handle the incoming messages and callbacks."""
|
|
while True:
|
|
data, addr = self.__sock.recvfrom(4096)
|
|
data = data.decode()
|
|
logging.debug("received %s", data)
|
|
channels, message = data.split(":", 1)
|
|
channels = channels.split(" ")
|
|
|
|
for event, callback in self.__callbacks:
|
|
if event(channels, message):
|
|
logging.info("passed %s", event.__name__)
|
|
callback(channels, message)
|