# HG changeset patch # User Paul Boddie # Date 1422403464 -3600 # Node ID 2527a2230686cf6f67e60cd7fd88ff0dadaa8857 # Parent c4630b004a309ee876e120c7f41032174503ca18 Changed the responses from handlers to be collections of messages, with outgoing message usage made explicit, thus permitting multiple responses for certain methods. Made more widespread use of the special wrap method in the person handler for providing messages to recipients. diff -r c4630b004a30 -r 2527a2230686 imiptools/content.py --- a/imiptools/content.py Wed Jan 28 00:32:44 2015 +0100 +++ b/imiptools/content.py Wed Jan 28 01:04:24 2015 +0100 @@ -22,9 +22,11 @@ from datetime import datetime, timedelta from email.mime.text import MIMEText +from imiptools.config import MANAGER_PATH, MANAGER_URL from imiptools.dates import * from imiptools.period import have_conflict, insert_period, remove_period from pytz import timezone +from socket import gethostname from vCalendar import parse, ParseError, to_dict from vRecurrence import get_parameters, get_rule import email.utils @@ -277,14 +279,14 @@ # Dispatch to a handler and obtain any response. handler = cls(details, senders, recipient, messenger) - result = methods[method](handler)() + results = methods[method](handler)() # Aggregate responses for a single message. - if result: - response_method, part = result - outgoing = method != response_method - all_results.append((outgoing, part)) + if results: + for result in results: + outgoing, part = result + all_results.append((outgoing, part)) return all_results @@ -336,6 +338,15 @@ finally: out.close() +# References to the Web interface. + +def get_manager_url(): + url_base = MANAGER_URL or "http://%s/" % gethostname() + return "%s/%s" % (url_base.rstrip("/"), MANAGER_PATH.lstrip("/")) + +def get_object_url(uid): + return "%s/%s" % (get_manager_url().rstrip("/"), uid) + class Handler: "General handler support." @@ -363,6 +374,19 @@ except OSError: self.publisher = None + def wrap(self, text, link=True): + + "Wrap any valid message for passing to the recipient." + + texts = [] + texts.append(text) + if link: + texts.append("If your mail program cannot handle this " + "message, you may view the details here:\n\n%s" % + get_object_url(self.uid)) + + return [(False, MIMEText("\n".join(texts)))] + # Access to calendar structures and other data. def get_items(self, name, all=True): diff -r c4630b004a30 -r 2527a2230686 imiptools/handlers/common.py --- a/imiptools/handlers/common.py Wed Jan 28 00:32:44 2015 +0100 +++ b/imiptools/handlers/common.py Wed Jan 28 01:04:24 2015 +0100 @@ -36,7 +36,7 @@ # Return the reply. - return "REPLY", to_part("REPLY", calendar) + return [(True, to_part("REPLY", calendar))] def make_freebusy_to_publish(self, from_organiser=True): @@ -50,7 +50,7 @@ # Return a published object. - return "PUBLISH", to_part("PUBLISH", calendar) + return [(True, to_part("PUBLISH", calendar))] def make_freebusy(self, from_organiser=True, publish=False): diff -r c4630b004a30 -r 2527a2230686 imiptools/handlers/person.py --- a/imiptools/handlers/person.py Wed Jan 28 00:32:44 2015 +0100 +++ b/imiptools/handlers/person.py Wed Jan 28 01:04:24 2015 +0100 @@ -19,21 +19,11 @@ this program. If not, see . """ -from email.mime.text import MIMEText -from imiptools.config import MANAGER_PATH, MANAGER_URL from imiptools.content import Handler, get_address, get_uri, to_part, uri_dict, uri_items from imiptools.handlers.common import CommonFreebusy from imiptools.profile import Preferences -from socket import gethostname from vCalendar import to_node -def get_manager_url(): - url_base = MANAGER_URL or "http://%s/" % gethostname() - return "%s/%s" % (url_base.rstrip("/"), MANAGER_PATH.lstrip("/")) - -def get_object_url(uid): - return "%s/%s" % (get_manager_url().rstrip("/"), uid) - class PersonHandler(Handler): "Handling mechanisms specific to people." @@ -134,19 +124,6 @@ for sender, sender_attr in uri_items(self.get_items(from_organiser and "ORGANIZER" or "ATTENDEE")): self.store.set_freebusy_for_other(get_uri(self.recipient), freebusy, sender) - def wrap(self, method, text, from_organiser=True, link=True): - - "Wrap any valid message and pass it on to the recipient." - - texts = [] - texts.append(text) - if link: - texts.append("If your mail program cannot handle this " - "message, you may view the details here:\n\n%s" % - get_object_url(self.uid)) - - return method, MIMEText("\n".join(texts)) - class Event(PersonHandler): "An event handler." @@ -155,63 +132,54 @@ # NOTE: Queue a suggested modification to any active event. - # The message is now wrapped and passed on to the recipient. - - return "ADD", MIMEText("An addition to an event has been received.") + return self.wrap("An addition to an event has been received.", link=False) def cancel(self): "Queue a cancellation of any active event." self._record_and_deliver("VEVENT", from_organiser=True, queue=False, cancel=True) - return self.wrap("CANCEL", "A cancellation has been received.", from_organiser=True, link=True) + return self.wrap("A cancellation has been received.", link=False) def counter(self): # NOTE: Queue a suggested modification to any active event. - # The message is now wrapped and passed on to the recipient. - - return "COUNTER", MIMEText("A counter proposal has been received.") + return self.wrap("A counter proposal has been received.", link=False) def declinecounter(self): # NOTE: Queue a suggested modification to any active event. - # The message is now wrapped and passed on to the recipient. - - return "DECLINECOUNTER", MIMEText("A declining counter proposal has been received.") + return self.wrap("A declining counter proposal has been received.", link=False) def publish(self): "Register details of any relevant event." self._record_and_deliver("VEVENT", from_organiser=True, queue=False) - return self.wrap("PUBLISH", "Details of an event have been received.", from_organiser=True, link=True) + return self.wrap("Details of an event have been received.") def refresh(self): "Update details of any active event." self._record_and_deliver("VEVENT", from_organiser=True, queue=False) - return self.wrap("REFRESH", "An event update has been received.", from_organiser=True, link=True) + return self.wrap("An event update has been received.") def reply(self): "Record replies and notify the recipient." self._record_and_deliver("VEVENT", from_organiser=False, queue=False) - return self.wrap("REPLY", "A reply has been received.", from_organiser=False, link=True) + return self.wrap("A reply has been received.") def request(self): "Hold requests and notify the recipient." self._record_and_deliver("VEVENT", from_organiser=True, queue=True) - - # The message is now wrapped and passed on to the recipient. - - return "REQUEST", MIMEText("A request has been queued and can be viewed here: %s" % get_object_url(self.uid)) + return self.wrap("A request has been received.") class Freebusy(PersonHandler, CommonFreebusy): @@ -227,7 +195,7 @@ preferences = Preferences(get_uri(self.recipient)) if preferences.get("freebusy_messages") == "notify": - return self.wrap("PUBLISH", "A free/busy update has been received.", from_organiser=True, link=False) + return self.wrap("A free/busy update has been received.", link=False) def reply(self): @@ -239,7 +207,7 @@ preferences = Preferences(get_uri(self.recipient)) if preferences.get("freebusy_messages") == "notify": - return self.wrap("REPLY", "A reply to a free/busy request has been received.", from_organiser=False, link=False) + return self.wrap("A reply to a free/busy request has been received.", link=False) def request(self): @@ -262,26 +230,20 @@ # NOTE: Queue a suggested modification to any active entry. - # The message is now wrapped and passed on to the recipient. - - return "ADD", MIMEText("An addition to a journal entry has been received.") + return self.wrap("An addition to a journal entry has been received.", link=False) def cancel(self): # NOTE: Queue a suggested modification to any active entry. - # The message is now wrapped and passed on to the recipient. - - return "CANCEL", MIMEText("A cancellation has been received.") + return self.wrap("A cancellation has been received.", link=False) def publish(self): # NOTE: Register details of any relevant entry. - # The message is now wrapped and passed on to the recipient. - self._record_and_deliver("VJOURNAL", from_organiser=True, queue=False) - return self.wrap("PUBLISH", "Details of a journal entry have been received.", from_organiser=True, link=False) + return self.wrap("Details of a journal entry have been received.") class Todo(PersonHandler): @@ -291,64 +253,53 @@ # NOTE: Queue a suggested modification to any active item. - # The message is now wrapped and passed on to the recipient. - - return "ADD", MIMEText("An addition to an item has been received.") + return self.wrap("An addition to an item has been received.", link=False) def cancel(self): # NOTE: Queue a suggested modification to any active item. - # The message is now wrapped and passed on to the recipient. - - return "CANCEL", MIMEText("A cancellation has been received.") + return self.wrap("A cancellation has been received.", link=False) def counter(self): # NOTE: Queue a suggested modification to any active item. - # The message is now wrapped and passed on to the recipient. - - return "COUNTER", MIMEText("A counter proposal has been received.") + return self.wrap("A counter proposal has been received.", link=False) def declinecounter(self): # NOTE: Queue a suggested modification to any active item. - # The message is now wrapped and passed on to the recipient. - - return "DECLINECOUNTER", MIMEText("A declining counter proposal has been received.") + return self.wrap("A declining counter proposal has been received.", link=False) def publish(self): "Register details of any relevant item." self._record_and_deliver("VTODO", from_organiser=True, queue=False) - return self.wrap("PUBLISH", "Details of an item have been received.", from_organiser=True, link=True) + return self.wrap("Details of an item have been received.") def refresh(self): "Update details of any active item." self._record_and_deliver("VTODO", from_organiser=True, queue=False) - return self.wrap("REFRESH", "An item update has been received.", from_organiser=True, link=True) + return self.wrap("An item update has been received.") def reply(self): "Record replies and notify the recipient." self._record_and_deliver("VTODO", from_organiser=False, queue=False) - return self.wrap("REPLY", "A reply has been received.", from_organiser=False, link=True) + return self.wrap("A reply has been received.") def request(self): "Hold requests and notify the recipient." self._record_and_deliver("VTODO", from_organiser=True, queue=True) - - # The message is now wrapped and passed on to the recipient. - - return "REQUEST", MIMEText("A request has been queued.") + return self.wrap("A request has been received.") # Handler registry. diff -r c4630b004a30 -r 2527a2230686 imiptools/handlers/resource.py --- a/imiptools/handlers/resource.py Wed Jan 28 00:32:44 2015 +0100 +++ b/imiptools/handlers/resource.py Wed Jan 28 01:04:24 2015 +0100 @@ -153,7 +153,7 @@ response = self._record_and_respond(self._schedule_for_attendee) if response: - return "REPLY", to_part("REPLY", response) + return [(True, to_part("REPLY", response))] else: return None