95 lines
3.9 KiB
Python
95 lines
3.9 KiB
Python
import json
|
|
import requests as r
|
|
import logging
|
|
import time
|
|
import datetime
|
|
from functools import wraps
|
|
from threading import Thread
|
|
from irc import IRC
|
|
|
|
from sasl import nick, password
|
|
|
|
|
|
class Shoutbox(object):
|
|
def __init__(self, cookies):
|
|
self.channels = {'annonces': 0, 'projets': 0, 'hs': 0}
|
|
self.cookies = cookies
|
|
self._callbacks = []
|
|
self.irc_clients = {} # pseudo: [IRC(), date]
|
|
|
|
for channel, last_id in self.channels.items():
|
|
messages = json.loads(r.get(f"https://www.planet-casio.com/Fr/shoutbox/api/read?since={last_id}&channel={channel}&format=text").text)['messages']
|
|
for m in messages:
|
|
self.channels[channel] = m['id']
|
|
|
|
def run(self):
|
|
def handler():
|
|
while True:
|
|
for channel, last_id in self.channels.items():
|
|
messages = json.loads(r.get(f"https://www.planet-casio.com/Fr/shoutbox/api/read?since={last_id}&channel={channel}&format=text").text)['messages']
|
|
for m in messages:
|
|
logging.debug(m)
|
|
self.channels[channel] = m['id']
|
|
message = SBMessage(m, channel)
|
|
for event, callback in self._callbacks:
|
|
# client is not known or is disconnected
|
|
author = Shoutbox.normalize(message.author)
|
|
if author not in self.irc_clients \
|
|
or self.irc_clients[author][0].run == False:
|
|
self.irc_clients[author] = [
|
|
IRC('irc.planet-casio.com', 6697),
|
|
datetime.datetime.now()
|
|
]
|
|
self.irc_clients[author][0].start(f"{author}[s]", password, nick)
|
|
logging.debug(f"{author} has joined IRC")
|
|
# client is known but AFK
|
|
else:
|
|
self.irc_clients[author][1] = datetime.datetime.now()
|
|
logging.debug(f"{author} has updated IRC")
|
|
|
|
if event(message):
|
|
logging.info(f"matched {event.__name__}")
|
|
callback(message)
|
|
# kill afk clients
|
|
for c in self.irc_clients.values():
|
|
if datetime.datetime.now() - c[1] > datetime.timedelta(hours=1):
|
|
c[0].stop()
|
|
time.sleep(1)
|
|
Thread(target=handler).start()
|
|
|
|
def on(self, event):
|
|
""" Adds a callback to the IRC handler
|
|
Event is a function taking in parameter a SBMessage and returning
|
|
True if the callback should be executed on the message """
|
|
|
|
def callback(func):
|
|
@wraps(func)
|
|
def wrapper(message):
|
|
func(message)
|
|
self._callbacks.append((event, wrapper))
|
|
logging.info(f"added callback {func.__name__}")
|
|
return wrapper
|
|
|
|
return callback
|
|
|
|
def post(self, user, msg, channel, users):
|
|
if any(user in t for t in users):
|
|
for i in users:
|
|
if i[1] == user:
|
|
r.post("https://www.planet-casio.com/Fr/shoutbox/api/post-as",
|
|
data={"user": i[0], "message": msg, "channel": channel},
|
|
cookies=self.cookies)
|
|
else:
|
|
r.post("https://www.planet-casio.com/Fr/shoutbox/api/post-as",
|
|
data={"user": "IRC", "message": f"{user} : {msg}", "channel": channel},
|
|
cookies=self.cookies)
|
|
|
|
def normalize(pseudo):
|
|
return pseudo.replace(' ', '_')
|
|
|
|
class SBMessage(object):
|
|
def __init__(self, raw, channel):
|
|
self.author = raw['author']
|
|
self.channel = channel
|
|
self.text = raw['content']
|