Things are less hacky now. WIP
This commit is contained in:
parent
b35593b89d
commit
fe33a5a0e4
|
|
@ -27,5 +27,5 @@ async def channel_check_callback(slack: SlackClient, msg: dict, match: Match) ->
|
|||
slack_util.reply(slack, msg, response)
|
||||
|
||||
|
||||
channel_check_hook = slack_util.Hook(channel_check_callback,
|
||||
patterns=r"channel id\s*(.*)")
|
||||
channel_check_hook = slack_util.ChannelHook(channel_check_callback,
|
||||
patterns=r"channel id\s*(.*)")
|
||||
|
|
|
|||
|
|
@ -123,5 +123,5 @@ class ClientWrapper(object):
|
|||
_singleton = ClientWrapper()
|
||||
|
||||
|
||||
def get_client_wrapper() -> ClientWrapper:
|
||||
def grab() -> ClientWrapper:
|
||||
return _singleton
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ def lookup_brother_userids(brother: scroll_util.Brother) -> List[str]:
|
|||
return result
|
||||
|
||||
|
||||
identify_hook = slack_util.Hook(identify_callback, patterns=r"my scroll is (.*)")
|
||||
identify_other_hook = slack_util.Hook(identify_other_callback, patterns=r"<@(.*)>\s+has scroll\s+(.*)")
|
||||
check_hook = slack_util.Hook(check_callback, patterns=r"what is my scroll")
|
||||
name_hook = slack_util.Hook(name_callback, patterns=r"what is my name")
|
||||
identify_hook = slack_util.ChannelHook(identify_callback, patterns=r"my scroll is (.*)")
|
||||
identify_other_hook = slack_util.ChannelHook(identify_other_callback, patterns=r"<@(.*)>\s+has scroll\s+(.*)")
|
||||
check_hook = slack_util.ChannelHook(check_callback, patterns=r"what is my scroll")
|
||||
name_hook = slack_util.ChannelHook(name_callback, patterns=r"what is my name")
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ async def _mod_jobs(slack: SlackClient,
|
|||
new_hook = slack_util.ReplyWaiter(foc, pattern, msg["ts"], 120)
|
||||
|
||||
# Register it
|
||||
client_wrapper.get_client_wrapper().add_hook(new_hook)
|
||||
client_wrapper.grab().add_hook(new_hook)
|
||||
|
||||
|
||||
async def signoff_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
||||
|
|
@ -351,50 +351,50 @@ async def nag_callback(slack, msg, match):
|
|||
slack_util.reply(slack, msg, response, in_thread=False, to_channel=channel_util.GENERAL)
|
||||
|
||||
|
||||
signoff_hook = slack_util.Hook(signoff_callback,
|
||||
patterns=[
|
||||
signoff_hook = slack_util.ChannelHook(signoff_callback,
|
||||
patterns=[
|
||||
r"signoff\s+(.*)",
|
||||
r"sign off\s+(.*)",
|
||||
],
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
|
||||
undo_hook = slack_util.Hook(undo_callback,
|
||||
patterns=[
|
||||
undo_hook = slack_util.ChannelHook(undo_callback,
|
||||
patterns=[
|
||||
r"unsignoff\s+(.*)",
|
||||
r"undosignoff\s+(.*)",
|
||||
r"undo signoff\s+(.*)",
|
||||
],
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
|
||||
late_hook = slack_util.Hook(late_callback,
|
||||
patterns=[
|
||||
late_hook = slack_util.ChannelHook(late_callback,
|
||||
patterns=[
|
||||
r"marklate\s+(.*)",
|
||||
r"mark late\s+(.*)",
|
||||
],
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
|
||||
reset_hook = slack_util.Hook(reset_callback,
|
||||
patterns=[
|
||||
reset_hook = slack_util.ChannelHook(reset_callback,
|
||||
patterns=[
|
||||
r"reset signoffs",
|
||||
r"reset sign offs",
|
||||
],
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
|
||||
nag_hook = slack_util.Hook(nag_callback,
|
||||
patterns=[
|
||||
nag_hook = slack_util.ChannelHook(nag_callback,
|
||||
patterns=[
|
||||
r"nagjobs\s+(.*)",
|
||||
r"nag jobs\s+(.*)"
|
||||
],
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
|
||||
reassign_hook = slack_util.Hook(reassign_callback,
|
||||
patterns=r"reassign\s+(.*?)->\s+(.+)",
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
reassign_hook = slack_util.ChannelHook(reassign_callback,
|
||||
patterns=r"reassign\s+(.*?)->\s+(.+)",
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
|
||||
refresh_hook = slack_util.Hook(refresh_callback,
|
||||
patterns=[
|
||||
refresh_hook = slack_util.ChannelHook(refresh_callback,
|
||||
patterns=[
|
||||
"refresh points",
|
||||
"update points"
|
||||
],
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID]
|
||||
)
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID]
|
||||
)
|
||||
|
|
|
|||
4
main.py
4
main.py
|
|
@ -16,7 +16,7 @@ import slavestothemachine
|
|||
|
||||
|
||||
def main() -> None:
|
||||
wrap = client_wrapper.get_client_wrapper()
|
||||
wrap = client_wrapper.grab()
|
||||
|
||||
# Add scroll handling
|
||||
wrap.add_hook(scroll_util.scroll_hook)
|
||||
|
|
@ -46,7 +46,7 @@ def main() -> None:
|
|||
wrap.add_hook(job_commands.refresh_hook)
|
||||
|
||||
# Add help
|
||||
wrap.add_hook(slack_util.Hook(help_callback, patterns=[r"help", r"bot\s+help"]))
|
||||
wrap.add_hook(slack_util.ChannelHook(help_callback, patterns=[r"help", r"bot\s+help"]))
|
||||
|
||||
# Add boozebot
|
||||
# wrap.add_passive(periodicals.ItsTenPM())
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import channel_util
|
|||
import slack_util
|
||||
|
||||
|
||||
def list_hooks_callback_gen(hooks: List[slack_util.Hook]) -> slack_util.Callback:
|
||||
def list_hooks_callback_gen(hooks: List[slack_util.ChannelHook]) -> slack_util.Callback:
|
||||
# noinspection PyUnusedLocal
|
||||
async def callback(slack, msg, match):
|
||||
slack_util.reply(slack, msg, "\n".join(hook.patterns for hook in hooks))
|
||||
|
|
@ -23,6 +23,6 @@ async def reboot_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
|||
|
||||
|
||||
# Make hooks
|
||||
reboot_hook = slack_util.Hook(reboot_callback,
|
||||
patterns=r"reboot",
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
reboot_hook = slack_util.ChannelHook(reboot_callback,
|
||||
patterns=r"reboot",
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
|
|
|
|||
|
|
@ -105,4 +105,4 @@ async def find_by_name(name: str, threshold: Optional[float] = None) -> Brother:
|
|||
raise BrotherNotFound(msg)
|
||||
|
||||
|
||||
scroll_hook = slack_util.Hook(scroll_callback, patterns=r"scroll\s+(.*)")
|
||||
scroll_hook = slack_util.ChannelHook(scroll_callback, patterns=r"scroll\s+(.*)")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
from __future__ import annotations
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from time import sleep, time
|
||||
from typing import Any, Optional, Generator, Match, Callable, List, Coroutine, Union, TypeVar, Awaitable
|
||||
|
||||
|
|
@ -10,9 +12,10 @@ Slack helpers. Separated for compartmentalization
|
|||
"""
|
||||
|
||||
|
||||
def reply(slack: SlackClient, msg: dict, text: str, in_thread: bool = True, to_channel: str = None) -> dict:
|
||||
def reply(msg: dict, text: str, in_thread: bool = True, to_channel: str = None) -> dict:
|
||||
"""
|
||||
Sends message with "text" as its content to the channel that message came from
|
||||
Sends message with "text" as its content to the channel that message came from.
|
||||
Returns the JSON response.
|
||||
"""
|
||||
# If no channel specified, just do same as msg
|
||||
if to_channel is None:
|
||||
|
|
@ -27,9 +30,10 @@ def reply(slack: SlackClient, msg: dict, text: str, in_thread: bool = True, to_c
|
|||
return send_message(slack, text, to_channel)
|
||||
|
||||
|
||||
def send_message(slack: SlackClient, text: str, channel: str, thread: str = None, broadcast: bool = False) -> dict:
|
||||
def send_message(text: str, channel: str, thread: str = None, broadcast: bool = False) -> dict:
|
||||
"""
|
||||
Copy of the internal send message function of slack
|
||||
Copy of the internal send message function of slack, with some helpful options.
|
||||
Returns the JSON response.
|
||||
"""
|
||||
kwargs = {"channel": channel, "text": text}
|
||||
if thread:
|
||||
|
|
@ -40,7 +44,58 @@ def send_message(slack: SlackClient, text: str, channel: str, thread: str = None
|
|||
return slack.api_call("chat.postMessage", **kwargs)
|
||||
|
||||
|
||||
def message_stream(slack: SlackClient) -> Generator[dict, None, None]:
|
||||
"""
|
||||
Objects to represent things
|
||||
"""
|
||||
class User:
|
||||
pass
|
||||
|
||||
class Channel:
|
||||
@property
|
||||
def channel_name(self) -> str:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Below we have a modular system that represents possible event contents.
|
||||
"""
|
||||
@dataclass
|
||||
class Event:
|
||||
channel: Optional[ChannelContext]
|
||||
user: Optional[UserContext]
|
||||
message: Optional[Message]
|
||||
|
||||
|
||||
# If this was posted in a specific channel or conversation
|
||||
@dataclass
|
||||
class ChannelContext:
|
||||
channel_id: str
|
||||
|
||||
|
||||
# If there is a specific user associated with this event
|
||||
@dataclass
|
||||
class UserContext:
|
||||
user_id: str
|
||||
|
||||
def as_user(self) -> User:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
# Whether or not this is a threadable text message
|
||||
@dataclass
|
||||
class Message:
|
||||
ts: str
|
||||
text: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class File:
|
||||
pass
|
||||
|
||||
|
||||
def message_stream(slack: SlackClient) -> Generator[Event, None, None]:
|
||||
"""
|
||||
Generator that yields messages from slack.
|
||||
Messages are in standard api format, look it up.
|
||||
|
|
@ -83,35 +138,41 @@ class VerboseWrapper(Callable):
|
|||
try:
|
||||
return await awt
|
||||
except Exception as e:
|
||||
reply(self.slack, self.command_msg, "Error: {}".format(str(e)), True)
|
||||
reply(self.command_msg, "Error: {}".format(str(e)), True)
|
||||
raise e
|
||||
|
||||
|
||||
# The result of a message
|
||||
MsgAction = Coroutine[Any, Any, None]
|
||||
Callback = Callable[[SlackClient, dict, Match], MsgAction]
|
||||
# The function called on a message
|
||||
Callback = Callable[[SlackClient, Message, Match], MsgAction]
|
||||
|
||||
|
||||
class DeadHook(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# Abstract hook parent class
|
||||
class AbsHook(object):
|
||||
def __init__(self, consumes_applicable: bool):
|
||||
# Whether or not messages that yield a coroutine should not be checked further
|
||||
self.consumes = consumes_applicable
|
||||
|
||||
def try_apply(self, slack: SlackClient, msg: dict) -> Optional[Coroutine[None, None, None]]:
|
||||
def try_apply(self, event: Event) -> Optional[MsgAction]:
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class Hook(AbsHook):
|
||||
class ChannelHook(AbsHook):
|
||||
"""
|
||||
Hook that handles messages in a variety of channels
|
||||
"""
|
||||
def __init__(self,
|
||||
callback: Callback,
|
||||
patterns: Union[str, List[str]],
|
||||
channel_whitelist: Optional[List[str]] = None,
|
||||
channel_blacklist: Optional[List[str]] = None,
|
||||
consumer: bool = True):
|
||||
super(Hook, self).__init__(consumer)
|
||||
super(ChannelHook, self).__init__(consumer)
|
||||
|
||||
# Save all
|
||||
if not isinstance(patterns, list):
|
||||
|
|
@ -131,7 +192,7 @@ class Hook(AbsHook):
|
|||
else:
|
||||
raise ValueError("Cannot whitelist and blacklist")
|
||||
|
||||
def try_apply(self, slack: SlackClient, msg: dict) -> Optional[Coroutine[None, None, None]]:
|
||||
def try_apply(self, event: Event) -> Optional[MsgAction]:
|
||||
"""
|
||||
Returns whether a message should be handled by this dict, returning a Match if so, or None
|
||||
"""
|
||||
|
|
@ -170,7 +231,7 @@ class ReplyWaiter(AbsHook):
|
|||
self.start_time = time()
|
||||
self.dead = False
|
||||
|
||||
def try_apply(self, slack: SlackClient, msg: dict) -> Optional[Coroutine[None, None, None]]:
|
||||
def try_apply(self, event: Event) -> Optional[MsgAction]:
|
||||
# First check: are we dead of age yet?
|
||||
time_alive = time() - self.start_time
|
||||
should_expire = time_alive > self.lifetime
|
||||
|
|
@ -199,6 +260,6 @@ class Passive(object):
|
|||
Base class for Periodical tasks, such as reminders and stuff
|
||||
"""
|
||||
|
||||
async def run(self, slack: SlackClient) -> None:
|
||||
async def run(self) -> None:
|
||||
# Run this passive routed through the specified slack client.
|
||||
raise NotImplementedError()
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ async def record_towel_contribution(for_brother: Brother, contribution_count: in
|
|||
|
||||
|
||||
# Make dem HOOKs
|
||||
count_work_hook = slack_util.Hook(count_work_callback,
|
||||
patterns=".*",
|
||||
channel_whitelist=[channel_util.SLAVES_TO_THE_MACHINE_ID],
|
||||
consumer=False)
|
||||
count_work_hook = slack_util.ChannelHook(count_work_callback,
|
||||
patterns=".*",
|
||||
channel_whitelist=[channel_util.SLAVES_TO_THE_MACHINE_ID],
|
||||
consumer=False)
|
||||
|
|
|
|||
Loading…
Reference in New Issue