Semi-stable? Pingme works. Stability of websockets under asyncio uncertain
This commit is contained in:
parent
42f2a64967
commit
5f834e3409
|
|
@ -6,6 +6,7 @@ import slack_util
|
||||||
|
|
||||||
# Useful channels
|
# Useful channels
|
||||||
GENERAL = "C0CFHPNEM"
|
GENERAL = "C0CFHPNEM"
|
||||||
|
RANDOM = "C0CFDQWUW"
|
||||||
COMMAND_CENTER_ID = "GCR631LQ1"
|
COMMAND_CENTER_ID = "GCR631LQ1"
|
||||||
SLAVES_TO_THE_MACHINE_ID = "C9WUQBYNP"
|
SLAVES_TO_THE_MACHINE_ID = "C9WUQBYNP"
|
||||||
BOTZONE = "C3BF2MFKM"
|
BOTZONE = "C3BF2MFKM"
|
||||||
|
|
@ -26,4 +27,5 @@ async def channel_check_callback(slack: SlackClient, msg: dict, match: Match) ->
|
||||||
slack_util.reply(slack, msg, response)
|
slack_util.reply(slack, msg, response)
|
||||||
|
|
||||||
|
|
||||||
channel_check_hook = slack_util.Hook(channel_check_callback, pattern=r"channel id\s*(.*)")
|
channel_check_hook = slack_util.Hook(channel_check_callback,
|
||||||
|
pattern=r"channel id\s*(.*)")
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ def lookup_brother_userids(brother: scroll_util.Brother) -> List[str]:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
identify_hook = slack_util.Hook(identify_callback, pattern=r"i am (.*)")
|
identify_hook = slack_util.Hook(identify_callback, pattern=r"my scroll is (.*)")
|
||||||
identify_other_hook = slack_util.Hook(identify_other_callback, pattern=r"<@(.*)>\s+has scroll\s+(.*)")
|
identify_other_hook = slack_util.Hook(identify_other_callback, pattern=r"<@(.*)>\s+has scroll\s+(.*)")
|
||||||
check_hook = slack_util.Hook(check_callback, pattern=r"my scroll")
|
check_hook = slack_util.Hook(check_callback, pattern=r"what is my scroll")
|
||||||
name_hook = slack_util.Hook(name_callback, pattern=r"my name")
|
name_hook = slack_util.Hook(name_callback, pattern=r"what is my name")
|
||||||
|
|
|
||||||
36
main.py
36
main.py
|
|
@ -1,5 +1,5 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import List, Any, Match, AsyncGenerator
|
from typing import List, Any, AsyncGenerator
|
||||||
|
|
||||||
from slackclient import SlackClient # Obvious
|
from slackclient import SlackClient # Obvious
|
||||||
|
|
||||||
|
|
@ -8,6 +8,7 @@ import identifier
|
||||||
import job_nagger
|
import job_nagger
|
||||||
import job_signoff
|
import job_signoff
|
||||||
import management_commands
|
import management_commands
|
||||||
|
import periodicals
|
||||||
import scroll_util
|
import scroll_util
|
||||||
import slack_util
|
import slack_util
|
||||||
import slavestothemachine
|
import slavestothemachine
|
||||||
|
|
@ -56,16 +57,14 @@ def main() -> None:
|
||||||
help_callback = management_commands.list_hooks_callback_gen(wrap.hooks)
|
help_callback = management_commands.list_hooks_callback_gen(wrap.hooks)
|
||||||
wrap.add_hook(slack_util.Hook(help_callback, pattern=management_commands.bot_help_pattern))
|
wrap.add_hook(slack_util.Hook(help_callback, pattern=management_commands.bot_help_pattern))
|
||||||
|
|
||||||
# Schedule?
|
# Add boozebot
|
||||||
async def do_later(slk: SlackClient, msg: dict, match: Match):
|
wrap.add_passive(periodicals.ItsTenPM())
|
||||||
time = int(match.group(1))
|
|
||||||
await asyncio.sleep(time)
|
|
||||||
slack_util.reply(slk, msg, "hello!")
|
|
||||||
|
|
||||||
wrap.add_hook(slack_util.Hook(do_later, "pingme\s+(\d+)"))
|
|
||||||
|
|
||||||
event_loop = asyncio.get_event_loop()
|
event_loop = asyncio.get_event_loop()
|
||||||
event_loop.run_until_complete(wrap.listen())
|
message_handling = wrap.respond_messages()
|
||||||
|
passive_handling = wrap.run_passives()
|
||||||
|
both = asyncio.gather(message_handling, passive_handling)
|
||||||
|
event_loop.run_until_complete(both)
|
||||||
|
|
||||||
|
|
||||||
class ClientWrapper(object):
|
class ClientWrapper(object):
|
||||||
|
|
@ -88,10 +87,26 @@ class ClientWrapper(object):
|
||||||
# Hooks go regex -> callback on (slack, msg, match)
|
# Hooks go regex -> callback on (slack, msg, match)
|
||||||
self.hooks: List[slack_util.Hook] = []
|
self.hooks: List[slack_util.Hook] = []
|
||||||
|
|
||||||
|
# Periodicals are just wrappers around an iterable, basically
|
||||||
|
self.passives: List[slack_util.Passive] = []
|
||||||
|
|
||||||
|
# Scheduled events handling
|
||||||
|
def add_passive(self, per: slack_util.Passive) -> None:
|
||||||
|
self.passives.append(per)
|
||||||
|
|
||||||
|
async def run_passives(self) -> None:
|
||||||
|
# Make a task to repeatedly spawn each event
|
||||||
|
awaitables = [p.run(self.slack) for p in self.passives]
|
||||||
|
await asyncio.gather(*awaitables)
|
||||||
|
|
||||||
|
# Message handling
|
||||||
def add_hook(self, hook: slack_util.Hook) -> None:
|
def add_hook(self, hook: slack_util.Hook) -> None:
|
||||||
self.hooks.append(hook)
|
self.hooks.append(hook)
|
||||||
|
|
||||||
async def listen(self):
|
async def respond_messages(self) -> None:
|
||||||
|
"""
|
||||||
|
Asynchronous tasks that eternally reads and responds to messages.
|
||||||
|
"""
|
||||||
async for _ in self.spool_tasks():
|
async for _ in self.spool_tasks():
|
||||||
print("Handling a message...!")
|
print("Handling a message...!")
|
||||||
|
|
||||||
|
|
@ -108,6 +123,7 @@ class ClientWrapper(object):
|
||||||
|
|
||||||
# Strip garbage
|
# Strip garbage
|
||||||
msg['text'] = msg['text'].strip()
|
msg['text'] = msg['text'].strip()
|
||||||
|
print("Recv: \"{}\"".format(msg['text']))
|
||||||
|
|
||||||
# Handle debug
|
# Handle debug
|
||||||
if msg['text'][:6] == "DEBUG ":
|
if msg['text'][:6] == "DEBUG ":
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,6 @@ async def reboot_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
||||||
|
|
||||||
# Make hooks
|
# Make hooks
|
||||||
bot_help_pattern = r"bot help" # Can't init this directly, as it relies on us knowing all other hooks. handle in main
|
bot_help_pattern = r"bot help" # Can't init this directly, as it relies on us knowing all other hooks. handle in main
|
||||||
reboot_hook = slack_util.Hook(reboot_callback, pattern=r"reboot", channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
reboot_hook = slack_util.Hook(reboot_callback,
|
||||||
|
pattern=r"reboot",
|
||||||
|
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import asyncio
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from slackclient import SlackClient
|
||||||
|
|
||||||
|
import channel_util
|
||||||
|
import slack_util
|
||||||
|
|
||||||
|
|
||||||
|
def seconds_until(target: datetime) -> float:
|
||||||
|
curr = datetime.now()
|
||||||
|
delta = target - curr
|
||||||
|
return delta.seconds
|
||||||
|
|
||||||
|
|
||||||
|
class ItsTenPM(slack_util.Passive):
|
||||||
|
async def run(self, slack: SlackClient) -> None:
|
||||||
|
while True:
|
||||||
|
# Get 10PM
|
||||||
|
ten_pm = datetime.now().replace(hour=21, minute=0, second=0)
|
||||||
|
|
||||||
|
# Find out how long until it, then sleep that long
|
||||||
|
delay = seconds_until(ten_pm)
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
|
||||||
|
# Crow like a rooster
|
||||||
|
slack_util.reply(slack, {}, "IT'S 10 PM!", in_thread=False, to_channel=channel_util.RANDOM)
|
||||||
|
|
||||||
|
# Wait a while before trying it again, to prevent duplicates
|
||||||
|
await asyncio.sleep(60)
|
||||||
|
|
@ -20,6 +20,9 @@ class Brother(object):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.scroll = scroll
|
self.scroll = scroll
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Brother {}-{}>".format(self.name, self.scroll)
|
||||||
|
|
||||||
|
|
||||||
# load the family tree
|
# load the family tree
|
||||||
familyfile = open("sortedfamilytree.txt", 'r')
|
familyfile = open("sortedfamilytree.txt", 'r')
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import asyncio
|
|
||||||
import re
|
import re
|
||||||
|
from asyncio import Task
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import Any, Optional, Generator, Match, Callable, List, Coroutine
|
from typing import Any, Optional, Generator, Match, Callable, List, Coroutine, AsyncGenerator
|
||||||
|
|
||||||
from slackclient import SlackClient
|
from slackclient import SlackClient
|
||||||
|
|
||||||
|
|
@ -70,6 +70,7 @@ def message_stream(slack: SlackClient) -> Generator[dict, None, None]:
|
||||||
"""
|
"""
|
||||||
# Do forever
|
# Do forever
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
if slack.rtm_connect(with_team_state=False, auto_reconnect=True):
|
if slack.rtm_connect(with_team_state=False, auto_reconnect=True):
|
||||||
print("Waiting for messages")
|
print("Waiting for messages")
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -78,6 +79,11 @@ def message_stream(slack: SlackClient) -> Generator[dict, None, None]:
|
||||||
for item in update:
|
for item in update:
|
||||||
if item.get('type') == 'message':
|
if item.get('type') == 'message':
|
||||||
yield item
|
yield item
|
||||||
|
except OSError as e:
|
||||||
|
print("Error while reading messages:")
|
||||||
|
print(e)
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
print("Malformed message... Restarting connection")
|
||||||
|
|
||||||
sleep(5)
|
sleep(5)
|
||||||
print("Connection failed - retrying")
|
print("Connection failed - retrying")
|
||||||
|
|
@ -90,7 +96,7 @@ Callback = Callable[[SlackClient, dict, Match], MsgAction]
|
||||||
class Hook(object):
|
class Hook(object):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
callback: Callback,
|
callback: Callback,
|
||||||
pattern: str = None,
|
pattern: str,
|
||||||
channel_whitelist: Optional[List[str]] = None,
|
channel_whitelist: Optional[List[str]] = None,
|
||||||
channel_blacklist: Optional[List[str]] = None):
|
channel_blacklist: Optional[List[str]] = None):
|
||||||
# Save all
|
# Save all
|
||||||
|
|
@ -100,9 +106,6 @@ class Hook(object):
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
|
||||||
# Remedy some sensible defaults
|
# Remedy some sensible defaults
|
||||||
if self.pattern is None:
|
|
||||||
self.pattern = ".*"
|
|
||||||
|
|
||||||
if self.channel_blacklist is None:
|
if self.channel_blacklist is None:
|
||||||
import channel_util
|
import channel_util
|
||||||
self.channel_blacklist = [channel_util.GENERAL]
|
self.channel_blacklist = [channel_util.GENERAL]
|
||||||
|
|
@ -135,3 +138,12 @@ class Hook(object):
|
||||||
|
|
||||||
def invoke(self, slack: SlackClient, msg: dict, match: Match):
|
def invoke(self, slack: SlackClient, msg: dict, match: Match):
|
||||||
return self.callback(slack, msg, match)
|
return self.callback(slack, msg, match)
|
||||||
|
|
||||||
|
|
||||||
|
class Passive(object):
|
||||||
|
"""
|
||||||
|
Base class for Periodical tasks, such as reminders and stuff
|
||||||
|
"""
|
||||||
|
async def run(self, slack: SlackClient) -> None:
|
||||||
|
# Run this passive routed through the specified slack client.
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,9 @@ async def dump_work_callback(slack: SlackClient, msg: dict, match: Match) -> Non
|
||||||
|
|
||||||
|
|
||||||
# Make dem HOOKs
|
# Make dem HOOKs
|
||||||
count_work_hook = slack_util.Hook(count_work_callback, channel_whitelist=[channel_util.SLAVES_TO_THE_MACHINE_ID])
|
count_work_hook = slack_util.Hook(count_work_callback,
|
||||||
dump_work_hook = slack_util.Hook(dump_work_callback, pattern="dump towel data",
|
pattern=".*",
|
||||||
|
channel_whitelist=[channel_util.SLAVES_TO_THE_MACHINE_ID])
|
||||||
|
dump_work_hook = slack_util.Hook(dump_work_callback,
|
||||||
|
pattern="dump towel data",
|
||||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue