Added reply callback procedure?
This commit is contained in:
parent
716ec52a98
commit
1ddfa7403b
|
|
@ -70,6 +70,7 @@ class ClientWrapper(object):
|
||||||
# Strip garbage
|
# Strip garbage
|
||||||
msg['text'] = msg['text'].strip()
|
msg['text'] = msg['text'].strip()
|
||||||
print("Recv: \"{}\"".format(msg['text']))
|
print("Recv: \"{}\"".format(msg['text']))
|
||||||
|
print(msg)
|
||||||
|
|
||||||
# Msg is good
|
# Msg is good
|
||||||
# Find which hook, if any, satisfies
|
# Find which hook, if any, satisfies
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ class Job(object):
|
||||||
# Extra stuff, interpreted
|
# Extra stuff, interpreted
|
||||||
day: Optional[date]
|
day: Optional[date]
|
||||||
|
|
||||||
|
def pretty_fmt(self) -> str:
|
||||||
|
return "{} - {} at {}".format(self.name, self.day_of_week, self.house)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class JobAssignment(object):
|
class JobAssignment(object):
|
||||||
|
|
@ -53,7 +56,6 @@ class JobAssignment(object):
|
||||||
late = "y" if self.late else "n"
|
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
|
return self.job.name, self.job.house, self.job.day_of_week, self.assignee.name, signer_name, late
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PointStatus(object):
|
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)
|
house_management.export_points(headers, points)
|
||||||
|
|
||||||
# Then we respond cool!
|
# 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.assignee.name,
|
||||||
on_assign.job.house,
|
on_assign.job.pretty_fmt()))
|
||||||
on_assign.job.day_of_week,
|
|
||||||
on_assign.job.name))
|
|
||||||
alert_user(slack, on_assign.assignee, "Your house job was signed off")
|
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:
|
if len(closest_assigns) == 0:
|
||||||
slack_util.reply(slack, msg, "Unable to find any jobs assigned to brother {} "
|
slack_util.reply(slack, msg, "Unable to find any jobs assigned to brother {} "
|
||||||
"(identified as {}).".format(signee_name, signee.name))
|
"(identified as {}).".format(signee_name, signee.name))
|
||||||
return
|
|
||||||
|
|
||||||
# If theres only one job, sign it off
|
# If theres only one job, sign it off
|
||||||
elif len(closest_assigns) == 1:
|
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)
|
targ_assign_index = assigns.index(targ_assign)
|
||||||
|
|
||||||
do_signoff(slack, msg, targ_assign_index, signer)
|
do_signoff(slack, msg, targ_assign_index, signer)
|
||||||
return
|
|
||||||
|
|
||||||
# If theres multiple jobs, we need to get a follow up!
|
# If theres multiple jobs, we need to get a follow up!
|
||||||
else:
|
else:
|
||||||
slack_util.reply(slack, msg, "Dunno how to handle multiple jobs yet")
|
# Say we need more info
|
||||||
return
|
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
|
# noinspection PyUnusedLocal
|
||||||
|
|
@ -191,12 +213,12 @@ async def nag_callback(slack, msg, match):
|
||||||
|
|
||||||
|
|
||||||
signoff_hook = slack_util.Hook(signoff_callback,
|
signoff_hook = slack_util.Hook(signoff_callback,
|
||||||
pattern=r"testsignoff\s+(.*)",
|
pattern=r"signoff\s+(.*)",
|
||||||
channel_whitelist=[channel_util.HOUSEJOBS])
|
channel_whitelist=[channel_util.HOUSEJOBS])
|
||||||
|
|
||||||
reset_hook = slack_util.Hook(reset_callback,
|
reset_hook = slack_util.Hook(reset_callback,
|
||||||
pattern=r"testreset signoffs",
|
pattern=r"reset signoffs",
|
||||||
channel_whitelist=[channel_util.COMMAND_CENTER_ID]) # COMMAND_CENTER_ID
|
channel_whitelist=[channel_util.COMMAND_CENTER_ID])
|
||||||
|
|
||||||
nag_hook = slack_util.Hook(nag_callback,
|
nag_hook = slack_util.Hook(nag_callback,
|
||||||
pattern=r"nagjobs\s*(.*)",
|
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]
|
brothers: List[Brother] = [Brother(m.group(2), int(m.group(1))) for m in brothers_matches]
|
||||||
recent_brothers: List[Brother] = brothers[700:]
|
recent_brothers: List[Brother] = brothers[700:]
|
||||||
|
|
||||||
|
|
||||||
async def scroll_callback(slack: SlackClient, msg: dict, match: Match) -> None:
|
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.
|
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)
|
result = "Couldn't find brother {}".format(query)
|
||||||
|
|
||||||
# Respond
|
# Respond
|
||||||
slack_util.reply(slack, msg, result)
|
print(slack_util.reply(slack, msg, result))
|
||||||
|
|
||||||
|
|
||||||
def find_by_scroll(scroll: int) -> Optional[Brother]:
|
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)
|
"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.
|
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)
|
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
|
import re
|
||||||
from time import sleep
|
from time import sleep, time
|
||||||
from typing import Any, Optional, Generator, Match, Callable, List, Coroutine
|
from typing import Any, Optional, Generator, Match, Callable, List, Coroutine
|
||||||
|
|
||||||
from slackclient import SlackClient
|
from slackclient import SlackClient
|
||||||
|
|
@ -141,10 +141,47 @@ class Hook(AbsHook):
|
||||||
return self.callback(slack, msg, match)
|
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):
|
class Passive(object):
|
||||||
"""
|
"""
|
||||||
Base class for Periodical tasks, such as reminders and stuff
|
Base class for Periodical tasks, such as reminders and stuff
|
||||||
"""
|
"""
|
||||||
|
|
||||||
async def run(self, slack: SlackClient) -> None:
|
async def run(self, slack: SlackClient) -> None:
|
||||||
# Run this passive routed through the specified slack client.
|
# Run this passive routed through the specified slack client.
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue