Adjusted to adhere to the new generator decorator

This commit is contained in:
aewens 2019-05-18 19:48:31 -05:00
parent 0cddba95e7
commit b4dae0b99c
3 changed files with 115 additions and 84 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ abots/
abots
*.log
*.swp
test_*.py
settings.json
# ---> Python

194
client.py
View File

@ -1,8 +1,10 @@
#!/opt/abots/env/bin/python3
#!/usr/bin/env python3
from components import IRCSocketClient, Composer
from abots.net import PrefixSocketClient
from abots.helpers import Logger, infinitedict, isnumeric, coroutine
from abots.events import CoroEvent
from abots.helpers import Logger, infinitedict, isnumeric, coroutine, generator
from abots.helpers import jsto, jots
from time import sleep
from os import remove as delete_file
@ -27,91 +29,119 @@ irc_args = irc_host, irc_port, irc_timeout, True
irc_client, inbox, outbox, events = composer.start_socket(*irc_args)
irc_client.ready.wait()
name = "babili"
with open("settings.json", "r") as config:
settings = jsto(config.read())
assert isinstance(settings, dict), "Expected dict"
irc_settings = settings.get("irc", dict())
name = irc_settings.get("name", "")
password = irc_settings.get("password", "")
author = irc_settings.get("author", "")
auto_join = irc_settings.get("auto-join", list())
requirements = irc_settings.get("requirements", list())
require_met = CoroEvent()
@coroutine
def log(cancel):
try:
while True:
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("command", None) == "ERROR":
logger.error(meta.get("raw"))
continue
logger.debug(meta.get("raw"))
except GeneratorExit:
pass
def off(composer, sock):
sock.send("QUIT bye-bye!")
sleep(1)
sock.stop()
composer.kill_switch.set()
@coroutine
def stopper(cancel):
try:
while True:
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("nick", None) != "NickServ":
continue
if meta.get("command", None) != "NOTICE":
continue
params = composer.cleanup(meta.get("params", ""))
nickserv_complain = "please choose a different nick"
if nickserv_complain not in params:
continue
cancel()
sleep(0.01)
sock.send("QUIT bye-bye!")
sleep(1)
sock.stop()
composer.kill_switch.set()
break
except GeneratorExit:
pass
@generator
def log(event, cancel):
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("command", None) == "ERROR":
logger.error(meta.get("raw"))
event.set()
logger.debug(meta.get("raw"))
@coroutine
def init(cancel):
try:
while True:
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("source", None) != "server":
continue
if meta.get("command", None) != "NOTICE":
continue
if "hostname" not in meta.get("params", ""):
continue
cancel()
logger.debug(meta["raw"])
sleep(0.01)
sock.send("CAP LS")
break
except GeneratorExit:
pass
@generator
def pivot(event, cancel):
sock, line = (yield)
meta = composer.parse_message(line)
tags = meta.get("tags", dict())
if tags.get("account", None) != author:
return
if meta.get("command", None) != "PRIVMSG":
return
params = composer.cleanup(meta.get("params", ""))
source, message = params.split(" ", 1)
if message == "!quit":
cancel()
event.set()
off(composer, sock)
elif message == "!debug":
logger.debug(meta)
@coroutine
def caps(cancel):
try:
while True:
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("source", None) != "server":
continue
if meta.get("command", None) != "CAP":
continue
params = composer.cleanup(meta.get("params", ""))
if "* LS" in params:
capabilities = params.split("* LS", 1)[1].strip()
logger.debug(f"Capabilities: {capabilities}")
sock.send(f"CAP REQ :{capabilities}")
elif "* ACK" in params:
cancel()
composer.register_many([log, stopper])
logger.debug(f"ACK!")
sleep(0.01)
sock.send("CAP END")
sock.send(f"USER {name} - - -")
sock.send(f"NICK {name}")
@generator
def identify(event, cancel):
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("nick", None) != "NickServ":
return
if meta.get("command", None) != "NOTICE":
return
params = composer.cleanup(meta.get("params", ""))
nickserv_complain = "please choose a different nick"
if nickserv_complain not in params:
return
cancel()
sleep(0.01)
sock.send(f"PRIVMSG NickServ IDENTIFY {password}")
sleep(1)
composer.register(log)
for channel in auto_join:
sock.send(f"JOIN {channel}")
composer.register(pivot)
#off(composer, sock)
event.set()
@generator
def init(event, cancel):
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("source", None) != "server":
return
if meta.get("command", None) != "NOTICE":
return
if "hostname" not in meta.get("params", ""):
return
cancel()
logger.debug(meta["raw"])
sleep(0.01)
sock.send("CAP LS")
event.set()
@generator
def caps(event, cancel):
sock, line = (yield)
meta = composer.parse_message(line)
if meta.get("source", None) != "server":
return
if meta.get("command", None) != "CAP":
return
params = composer.cleanup(meta.get("params", ""))
if "* LS" in params:
capabilities = params.split("* LS", 1)[1].strip()
logger.debug(f"Capabilities: {capabilities}")
sock.send(f"CAP REQ :{capabilities}")
for cap in capabilities.split(" "):
if cap in requirements:
requirements.remove(cap)
if len(requirements) == 0:
require_met.set()
break
except GeneratorExit:
pass
elif "* ACK" in params:
cancel()
logger.debug(f"ACK!")
event.set()
if require_met.is_set():
composer.register(identify)
sleep(0.01)
sock.send("CAP END")
sock.send(f"USER {name} - - -")
sock.send(f"NICK {name}")
composer.register_many([init, caps])
composer.get_messages(irc_client)

View File

@ -1,5 +1,5 @@
from components import IRCSocketClient
from abots.events import AsyncEvent
from abots.events import CoroEvent
from abots.helpers import Logger, infinitedict, isnumeric, coroutine, sha256
from time import sleep
@ -10,7 +10,7 @@ class Composer:
def __init__(self, logger):
self.logger = logger
self._targets = dict()
self.kill_switch = AsyncEvent()
self.kill_switch = CoroEvent()
def start_socket(self, host, port, timeout=None, secure=False):
sock = IRCSocketClient(host, port, timeout=timeout, secure=secure)