Added reply callback procedure?
This commit is contained in:
parent
716ec52a98
commit
1ddfa7403b
|
|
@ -70,6 +70,7 @@ class ClientWrapper(object):
|
|||
# Strip garbage
|
||||
msg['text'] = msg['text'].strip()
|
||||
print("Recv: \"{}\"".format(msg['text']))
|
||||
print(msg)
|
||||
|
||||
# Msg is good
|
||||
# Find which hook, if any, satisfies
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class Job(object):
|
|||
# Extra stuff, interpreted
|
||||
day: Optional[date]
|
||||
|
||||
def pretty_fmt(self) -> str:
|
||||
return "{} - {} at {}".format(self.name, self.day_of_week, self.house)
|
||||
|
||||
|
||||
@dataclass
|
||||
class JobAssignment(object):
|
||||
|
|
@ -53,7 +56,6 @@ class JobAssignment(object):
|
|||
late = "y" if self.late else "n"
|
||||
return self.job.name, self.job.house, self.job.day_of_week, self.assignee.name, signer_name, late
|
||||
|
||||
|
||||
@dataclass
|
||||
class PointStatus(object):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -63,11 +63,9 @@ def do_signoff(slack: SlackClient, msg: dict, on_assign_index: int, by_brother:
|
|||
house_management.export_points(headers, points)
|
||||
|
||||
# Then we respond cool!
|
||||
slack_util.reply(slack, msg, "{} signed off {} for {} {} {}".format(on_assign.signer.name,
|
||||
slack_util.reply(slack, msg, "{} signed off {} for {}".format(on_assign.signer.name,
|
||||
on_assign.assignee.name,
|
||||
on_assign.job.house,
|
||||
on_assign.job.day_of_week,
|
||||
on_assign.job.name))
|
||||
on_assign.job.pretty_fmt()))
|
||||
alert_user(slack, on_assign.assignee, "Your house job was signed off")
|
||||
|
||||
|
||||
|
|
@ -108,7 +106,6 @@ async def signoff_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
|||
if len(closest_assigns) == 0:
|
||||
slack_util.reply(slack, msg, "Unable to find any jobs assigned to brother {} "
|
||||
"(identified as {}).".format(signee_name, signee.name))
|
||||
return
|
||||
|
||||
# If theres only one job, sign it off
|
||||
elif len(closest_assigns) == 1:
|
||||
|
|
@ -118,12 +115,37 @@ async def signoff_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
|||
targ_assign_index = assigns.index(targ_assign)
|
||||
|
||||
do_signoff(slack, msg, targ_assign_index, signer)
|
||||
return
|
||||
|
||||
# If theres multiple jobs, we need to get a follow up!
|
||||
else:
|
||||
slack_util.reply(slack, msg, "Dunno how to handle multiple jobs yet")
|
||||
return
|
||||
# Say we need more info
|
||||
job_list = "\n".join("{}: {}".format(i, a.job.pretty_fmt()) for i, a in enumerate(closest_assigns))
|
||||
slack_util.reply(slack, msg, "Multiple sign off options dectected for brother {}.\n"
|
||||
"Please enter the number corresponding to the job you wish to "
|
||||
"sign off:\n{}\nIf you do not respond within 60 seconds, the signoff will "
|
||||
"expire.".format(signee_name, job_list))
|
||||
|
||||
# Establish a follow up command pattern
|
||||
pattern = r"\d+"
|
||||
|
||||
# Make the follow up callback
|
||||
async def foc(_slack: SlackClient, _msg: dict, _match: Match) -> None:
|
||||
# Get the number out
|
||||
index = int(_match.group(0))
|
||||
|
||||
# Check that its valid
|
||||
if 0 <= index < len(closest_assigns):
|
||||
# We now know what we're trying to sign off!
|
||||
specific_targ_assign = closest_assigns[index]
|
||||
specific_targ_assign_index = assigns.index(specific_targ_assign)
|
||||
do_signoff(_slack, _msg, specific_targ_assign_index, signer)
|
||||
else:
|
||||
# They gave a bad index, or we were unable to find the assignment again.
|
||||
slack_util.reply(_slack, _msg, "Invalid job index / job unable to be found. Start over from the "
|
||||
"signoff step.")
|
||||
|
||||
# Make a listener hook
|
||||
slack_util.ReplyWaiter(foc, pattern, msg["ts"], 60)
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
|
|
@ -191,12 +213,12 @@ async def nag_callback(slack, msg, match):
|
|||
|
||||
|
||||
signoff_hook = slack_util.Hook(signoff_callback,
|
||||
pattern=r"testsignoff\s+(.*)",
|
||||
pattern=r"signoff\s+(.*)",
|
||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||
|
||||
reset_hook = slack_util.Hook(reset_callback,
|
||||
pattern=r"testreset signoffs",
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID]) # COMMAND_CENTER_ID
|
||||
pattern=r"reset signoffs",
|
||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||
|
||||
nag_hook = slack_util.Hook(nag_callback,
|
||||
pattern=r"nagjobs\s*(.*)",
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ brothers_matches = [m for m in brothers_matches if m]
|
|||
brothers: List[Brother] = [Brother(m.group(2), int(m.group(1))) for m in brothers_matches]
|
||||
recent_brothers: List[Brother] = brothers[700:]
|
||||
|
||||
|
||||
async def scroll_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
||||
"""
|
||||
Finds the scroll of a brother, or the brother of a scroll, based on msg text.
|
||||
|
|
@ -54,7 +55,7 @@ async def scroll_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
|||
result = "Couldn't find brother {}".format(query)
|
||||
|
||||
# Respond
|
||||
slack_util.reply(slack, msg, result)
|
||||
print(slack_util.reply(slack, msg, result))
|
||||
|
||||
|
||||
def find_by_scroll(scroll: int) -> Optional[Brother]:
|
||||
|
|
@ -82,7 +83,7 @@ class BadName(Exception):
|
|||
"match ratio {}. Please type name better.".format(self.name, self.score, self.threshold)
|
||||
|
||||
|
||||
def find_by_name(name: str, threshold: Optional[float] = None, recent_only: bool=False) -> Brother:
|
||||
def find_by_name(name: str, threshold: Optional[float] = None, recent_only: bool = False) -> Brother:
|
||||
"""
|
||||
Looks up a brother by name. Raises exception if threshold provided and not met.
|
||||
|
||||
|
|
@ -110,4 +111,4 @@ def find_by_name(name: str, threshold: Optional[float] = None, recent_only: bool
|
|||
raise BadName(found, score, threshold)
|
||||
|
||||
|
||||
scroll_hook = slack_util.Hook(scroll_callback, pattern=r"scroll\s+(.*)")
|
||||
scroll_hook = slack_util.Hook(scroll_callback, pattern=r"testscroll\s+(.*)")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import re
|
||||
from time import sleep
|
||||
from time import sleep, time
|
||||
from typing import Any, Optional, Generator, Match, Callable, List, Coroutine
|
||||
|
||||
from slackclient import SlackClient
|
||||
|
|
@ -141,10 +141,47 @@ class Hook(AbsHook):
|
|||
return self.callback(slack, msg, match)
|
||||
|
||||
|
||||
class ReplyWaiter(AbsHook):
|
||||
"""
|
||||
A special hook that only cares about replies to a given message.
|
||||
"""
|
||||
|
||||
def __init__(self, callback: Callback, pattern: str, thread_ts: str, lifetime: float):
|
||||
super().__init__(True)
|
||||
self.callback = callback
|
||||
self.pattern = pattern
|
||||
self.thread_ts = thread_ts
|
||||
self.lifetime = lifetime
|
||||
self.start_time = time()
|
||||
self.dead = False
|
||||
|
||||
def try_apply(self, slack: SlackClient, msg: dict) -> Optional[Coroutine[None, None, None]]:
|
||||
# First check: are we dead of age yet?
|
||||
time_alive = time() - self.start_time
|
||||
should_expire = time_alive < self.lifetime
|
||||
|
||||
# If so, give up the ghost
|
||||
if self.dead or should_expire:
|
||||
raise DeadHook()
|
||||
|
||||
# Otherwise proceed normally
|
||||
# Is the msg the one we care about? If not, ignore
|
||||
if msg.get("thread_ts", None) != self.thread_ts:
|
||||
return None
|
||||
|
||||
# Does it match the regex? if not, ignore
|
||||
match = re.match(self.pattern, msg['text'], flags=re.IGNORECASE)
|
||||
if match:
|
||||
return self.callback(slack, msg, match)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue