diff --git a/earwigbot/tasks/drn_clerkbot.py b/earwigbot/tasks/drn_clerkbot.py index 2e74e0a..8a77662 100644 --- a/earwigbot/tasks/drn_clerkbot.py +++ b/earwigbot/tasks/drn_clerkbot.py @@ -46,6 +46,16 @@ class DRNClerkBot(Task): STATUS_CLOSED = 7 STATUS_ARCHIVE = 8 + ALIASES = { + STATUS_NEW: ("",), + STATUS_OPEN: ("open", "active", "inprogress"), + STATUS_STALE: ("stale",), + STATUS_NEEDASSIST: ("needassist", "relist", "relisted"), + STATUS_REVIEW: ("review",), + STATUS_RESOLVED: ("resolved", "resolve"), + STATUS_CLOSED: ("closed", "close"), + } + def setup(self): """Hook called immediately after the task is loaded.""" cfg = self.config.tasks.get(self.name, {}) @@ -167,7 +177,8 @@ class DRNClerkBot(Task): re_id2 += "(.*?)\}\})()?" repl = ur"\1 " body = re.sub(re_id2, repl.format(id_), body) - case = _Case(id_, title, status, time()) + case = _Case(id_, title, status, self.STATUS_UNKNOWN, time(), + time(), False, False) cases.append(case) else: case.status = status @@ -188,20 +199,11 @@ class DRNClerkBot(Task): def read_status(self, body): """Parse the current status from a case body.""" - aliases = { - self.STATUS_NEW: ("",), - self.STATUS_OPEN: ("open", "active", "inprogress"), - self.STATUS_STALE: ("stale",), - self.STATUS_NEEDASSIST: ("needassist", "relist", "relisted"), - self.STATUS_REVIEW: ("review",), - self.STATUS_RESOLVED: ("resolved", "resolve"), - self.STATUS_CLOSED: ("closed", "close"), - } templ = re.escape(self.tl_status) status = re.search("\{\{" + templ + "\|?(.*?)\}\}", body, re.S|re.U) if not status: return self.STATUS_UNKNOWN - for option, names in aliases.iteritems(): + for option, names in self.ALIASES.iteritems(): if status.group(1).lower() in names: return option return self.STATUS_UNKNOWN @@ -226,35 +228,30 @@ class DRNClerkBot(Task): def clerk_case(self, conn, case, volunteers): """Clerk a particular case and return a list of any notices to send.""" notices = [] + signatures = self.read_signatures(case.body) if case.status == self.STATUS_NEW: - notices = self.clerk_new_case(case, volunteers) + notices = self.clerk_new_case(case, volunteers, signatures) elif case.status == self.STATUS_OPEN: notices = self.clerk_open_case(case) elif case.status == self.STATUS_NEEDASSIST: - notices = self.clerk_needassist_case(case, volunteers) + notices = self.clerk_needassist_case(case, volunteers, signatures) elif case.status == self.STATUS_STALE: - notices = self.clerk_stale_case(case) + notices = self.clerk_stale_case(case, signatures) elif case.status == self.STATUS_REVIEW: notices = self.clerk_review_case(case) elif case.status in [self.STATUS_RESOLVED, self.STATUS_CLOSED]: self.clerk_closed_case(conn) else: - LOG NOT SURE HOW TO DEAL WITH CASE + log = u"Unsure of how to deal with case {0} (title: {1})" + self.logger.error(log.format(case.id, case.title)) return notices - # STORE UPDATES IN DATABASE - # APPLY STATUS UPDATES TO CASE BODY + STORE UPDATES IN DATABASE + APPLY STATUS UPDATES TO CASE BODY return notices - def check_for_review(self, case): - if time() - case.file_time > 60 * 60 * 24 * 4: - if case.last_action != self.STATUS_REVIEW: - case.status = self.STATUS_REVIEW - return SEND_MESSAGE_TO_WT:DRN - - def clerk_new_case(self, case, volunteers): + def clerk_new_case(self, case, volunteers, signatures): notices = self.notify_parties(case) - signatures = self.read_signatures(case.body) if any([editor in volunteers for (editor, time) in signatures]): if case.last_action != self.STATUS_OPEN: case.status = self.STATUS_OPEN @@ -268,32 +265,30 @@ class DRNClerkBot(Task): if len(case.body) - SIZE_WHEN_LAST_VOLUNTEER_EDIT > 15000: if case.last_action != self.STATUS_NEEDASSIST: case.status = self.STATUS_NEEDASSIST - return SEND_MESSAGE_TO_WT:DRN + return self.build_talk_notice(self.STATUS_NEEDASSIST) - if time() - LAST_EDIT > 60 * 60 * 24 * 2: + if time() - case.modify_time > 60 * 60 * 24 * 2: if case.last_action != self.STATUS_STALE: case.status = self.STATUS_STALE - return SEND_MESSAGE_TO_WT:DRN + return self.build_talk_notice(self.STATUS_STALE) return [] - def clerk_needassist_case(self, case, volunteers): + def clerk_needassist_case(self, case, volunteers, signatures): flagged = self.check_for_review(case): if flagged: return flagged - signatures = self.read_signatures(case.body) newsigs = signatures - SIGNATURES_FROM_DATABASE if any([editor in volunteers for (editor, time) in newsigs]): if case.last_action != self.STATUS_OPEN: case.status = self.STATUS_OPEN return [] - def clerk_stale_case(self, case): + def clerk_stale_case(self, case, signatures): flagged = self.check_for_review(case): if flagged: return flagged - signatures = self.read_signatures(case.body) if signatures - SIGNATURES_FROM_DATABASE: if case.last_action != self.STATUS_OPEN: case.status = self.STATUS_OPEN @@ -306,18 +301,29 @@ class DRNClerkBot(Task): return [] def clerk_closed_case(self, case): - if time() - TIME_STATUS_SET AND LAST_EDIT > 60 * 60 * 24: + if time() - TIME_STATUS_SET > 60 * 60 * 24 and time() - case.modify_time > 60 * 60 * 24: case.status = self.STATUS_ARCHIVE ADD_ARCHIVE_TEMPLATE REMOVE_NOARCHIVE + def check_for_review(self, case): + if time() - case.file_time > 60 * 60 * 24 * 4: + if case.last_action != self.STATUS_REVIEW: + case.status = self.STATUS_REVIEW + return self.build_talk_notice(self.STATUS_REVIEW) + def read_signatures(self, text): - raise NotImplementedError() + raise NotImplementedError() # TODO + + def build_talk_notice(self, status): + param = self.ALIASES[status][0] + template = "{{subst:" + self.tl_notify_stale + "|" + param + "}} ~~~~" + return _Notice(self.talk, template) def notify_parties(self, case): if case.parties_notified: return - raise NotImplementedError() + raise NotImplementedError() # TODO case.parties_notified = True def save(self, page, cases, kwargs): @@ -358,7 +364,7 @@ class DRNClerkBot(Task): text = page.get() except exceptions.PageNotFoundError: text = "" - if notice.too_late in text: + if notice.too_late and notice.too_late in text: log = u"Skipping [[{0}]]; was already notified".format(target) self.logger.info(log) text += ("\n" if text else "") + template @@ -374,13 +380,14 @@ class DRNClerkBot(Task): class _Case(object): """A object representing a dispute resolution case.""" - def __init__(self, id_, title, status, last_action, file_time, + def __init__(self, id_, title, status, last_action, file_time, modify_time, parties_notified, very_old_notified): self.id = id_ self.title = title self.status = status self.last_action = last_action self.file_time = file_time + self.modify_time = modify_time self.parties_notified = parties_notified self.very_old_notified = very_old_notified @@ -391,7 +398,7 @@ class _Case(object): class _Notice(object): """An object representing a notice to be sent to a user or a page.""" - def __init__(self, target, template, too_late): + def __init__(self, target, template, too_late=None): self.target = target self.template = template self.too_late = too_late diff --git a/earwigbot/tasks/schema/drn_clerkbot.sql b/earwigbot/tasks/schema/drn_clerkbot.sql index 81739dc..ecf0920 100644 --- a/earwigbot/tasks/schema/drn_clerkbot.sql +++ b/earwigbot/tasks/schema/drn_clerkbot.sql @@ -19,6 +19,7 @@ CREATE TABLE `case` ( `case_status` int(2) unsigned DEFAULT NULL, `case_last_action` int(2) unsigned DEFAULT NULL, `case_file_time` int(10) unsigned DEFAULT NULL, + `case_modify_time` int(10) unsigned DEFAULT NULL, `case_parties_notified` tinyint(1) unsigned DEFAULT NULL, `case_very_old_notified` tinyint(1) unsigned DEFAULT NULL, PRIMARY KEY (`case_id`)