Add shout → IRC clients support
This commit is contained in:
parent
3f7b984a2f
commit
a1c7a592d6
|
@ -7,16 +7,16 @@ from cookies import cookies
|
|||
from sasl import nick, password
|
||||
from users import users
|
||||
|
||||
import time
|
||||
|
||||
LOG_FORMAT = "%(asctime)s [%(levelname)s] <%(filename)s> %(funcName)s: %(message)s"
|
||||
logging.basicConfig(format=LOG_FORMAT, level=logging.INFO)
|
||||
logging.basicConfig(format=LOG_FORMAT, level=logging.DEBUG)
|
||||
|
||||
channels = ["hs", "projets", "annonces"]
|
||||
|
||||
irc = IRC('irc.planet-casio.com', 6697)
|
||||
shoutbox = Shoutbox(cookies)
|
||||
|
||||
|
||||
@irc.on(lambda m: m.to[1:] in channels)
|
||||
def handle_irc(m):
|
||||
shoutbox.post(m.author, m.text, m.to[1:], users)
|
||||
|
@ -24,10 +24,11 @@ def handle_irc(m):
|
|||
|
||||
@shoutbox.on(lambda m: m.channel in channels and m.author != "IRC" and not m.text.endswith("[IRC]"))
|
||||
def handle_shoutbox(m):
|
||||
irc.send(f"#{m.channel}", f"{m.author}: {m.text}")
|
||||
author = Shoutbox.normalize(m.author)
|
||||
shoutbox.irc_clients[author][0].send(f"#{m.channel}", f"{m.text}")
|
||||
|
||||
|
||||
irc.start("Shoutbox", password, nick)
|
||||
irc.start("Shoutbox[darks]", password, nick)
|
||||
for c in channels:
|
||||
irc.join(f"#{c}")
|
||||
|
||||
|
|
12
irc.py
12
irc.py
|
@ -10,6 +10,7 @@ class IRC(object):
|
|||
""" Initialize an IRC wrapper """
|
||||
# Public attributes
|
||||
self.connected = False # Simple lock
|
||||
self.run = False
|
||||
|
||||
# Private attributes
|
||||
self._socket = ssl.create_default_context().wrap_socket(
|
||||
|
@ -24,6 +25,7 @@ class IRC(object):
|
|||
def start(self, nick, password, sasl_nick=None):
|
||||
""" Start the IRC layer. Manage authentication as well """
|
||||
sasl_nick = sasl_nick or nick
|
||||
self._run = True
|
||||
self._handler.start()
|
||||
|
||||
self._send(f"USER {nick} * * :{nick}")
|
||||
|
@ -36,7 +38,13 @@ class IRC(object):
|
|||
|
||||
def stop(self):
|
||||
""" Stop the IRC layer """
|
||||
self._handler.terminate()
|
||||
self._send("QUIT")
|
||||
logging.debug("STOP: sent QUIT message")
|
||||
self._run = False
|
||||
self._handler.join()
|
||||
logging.debug("STOP: thread has terminated")
|
||||
self._socket.close()
|
||||
logging.debug("STOP: socket close")
|
||||
|
||||
def run(self):
|
||||
""" Handle new messages """
|
||||
|
@ -87,7 +95,7 @@ class IRC(object):
|
|||
|
||||
def _handle(self, store=True):
|
||||
""" Handle raw messages from irc and manage ping """
|
||||
while True:
|
||||
while self._run:
|
||||
# Get incoming messages
|
||||
data = self._socket.recv(4096).decode()
|
||||
|
||||
|
|
26
shoutbox.py
26
shoutbox.py
|
@ -2,8 +2,12 @@ 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):
|
||||
|
@ -11,6 +15,7 @@ class Shoutbox(object):
|
|||
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']
|
||||
|
@ -27,9 +32,28 @@ class Shoutbox(object):
|
|||
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()
|
||||
|
||||
|
@ -60,6 +84,8 @@ class Shoutbox(object):
|
|||
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):
|
||||
|
|
Loading…
Reference in New Issue