# HG changeset patch # User Paul Boddie # Date 1414692499 -3600 # Node ID 0eba4667b645d7906fdcfd5d41cd36fd578361ca # Parent 7f76c5133b4627467cfd64c9dc30c4785bf01186 Added initial support for inspecting outgoing messages for calendar information. diff -r 7f76c5133b46 -r 0eba4667b645 conf/exim/010_exim4-config_people_outgoing --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/exim/010_exim4-config_people_outgoing Thu Oct 30 19:08:19 2014 +0100 @@ -0,0 +1,14 @@ +LDAP_PERSON_OUTGOING_QUERY = (&(|(mail=${quote_ldap:${sender_address_local_part}}@${sender_address_domain})(alias=${quote_ldap:${sender_address_local_part}}@${sender_address_domain}))(objectclass=kolabinetorgperson)) + +people_outgoing: + debug_print = "R: person_outgoing for $sender_address_local_part@$sender_address_domain" + driver = accept + unseen + no_expn + no_verify + condition = ${if eq {}{${lookup ldap{ \ + user="$ldap_service_bind_dn" \ + pass=$ldap_service_password \ + ldap://$ldap_host:$ldap_port/$ldap_base_dn?mail?sub?LDAP_PERSON_OUTGOING_QUERY} \ + }}{no}{yes}} + transport = people_outgoing_transport diff -r 7f76c5133b46 -r 0eba4667b645 conf/exim/30_exim4-config_people_outgoing --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf/exim/30_exim4-config_people_outgoing Thu Oct 30 19:08:19 2014 +0100 @@ -0,0 +1,6 @@ +people_outgoing_transport: + debug_print = "T: people_outgoing_transport for $local_part@$domain" + driver = pipe + command = /var/lib/imip-agent/imip_person_outgoing.py -O + user = imip-agent + initgroups = true diff -r 7f76c5133b46 -r 0eba4667b645 imip_person_outgoing.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imip_person_outgoing.py Thu Oct 30 19:08:19 2014 +0100 @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +from imiptools import Processor +from imiptools.handlers import person_outgoing +from imiptools.mail import Messenger + +Processor( + person_outgoing.handlers, + Messenger( + "imip-agent@example.com", + "Calendar system message", + "This is a message from the calendar system." + ) + )() + +# vim: tabstop=4 expandtab shiftwidth=4 diff -r 7f76c5133b46 -r 0eba4667b645 imiptools/__init__.py --- a/imiptools/__init__.py Thu Oct 30 19:07:40 2014 +0100 +++ b/imiptools/__init__.py Thu Oct 30 19:08:19 2014 +0100 @@ -33,7 +33,7 @@ self.messenger = messenger or Messenger() self.lmtp_socket = None - def process(self, f, original_recipients, recipients): + def process(self, f, original_recipients, recipients, outgoing_only): """ Process content from the stream 'f' accompanied by the given @@ -56,6 +56,12 @@ all_responses += handle_itip_part(part, senders, original_recipients, self.handlers, self.messenger) handled = True + # When processing outgoing messages, no replies or deliveries are + # performed. + + if outgoing_only: + return + # Pack any returned parts into a single message. if all_responses: @@ -109,11 +115,17 @@ recipients = [] senders = [] lmtp = [] + outgoing_only = False l = [] for arg in args: + # Detect outgoing processing mode. + + if arg == "-O": + outgoing_only = True + # Switch to collecting recipients. if arg == "-o": @@ -140,7 +152,7 @@ self.messenger.sender = senders and senders[0] or self.messenger.sender self.lmtp_socket = lmtp and lmtp[0] or None - self.process(stream, original_recipients, recipients) + self.process(stream, original_recipients, recipients, outgoing_only) def __call__(self): diff -r 7f76c5133b46 -r 0eba4667b645 imiptools/handlers/person_outgoing.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imiptools/handlers/person_outgoing.py Thu Oct 30 19:08:19 2014 +0100 @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +""" +Handlers for a person for whom scheduling is performed, inspecting outgoing +messages to obtain scheduling done externally. +""" + +from imiptools.content import Handler +from vCalendar import to_node + +class PersonHandler(Handler): + + "Handling mechanisms specific to people." + + def _record(self, objtype, from_organiser=True, update_freebusy=False): + identity = self.get_value(from_organiser and "ORGANIZER" or "ATTENDEE") + + # Store the object. + + self.store.set_event(identity, self.uid, to_node( + {objtype : [(self.details, {})]} + )) + + # Update free/busy information. + + if update_freebusy: + periods = self.get_periods() + freebusy = self.store.get_freebusy(identity) or [] + self.update_freebusy(freebusy, identity, periods) + if self.publisher: + self.publisher.set_freebusy(identity, freebusy) + + return True + +class Event(PersonHandler): + + "An event handler." + + def add(self): + pass + + def cancel(self): + pass + + def counter(self): + pass + + def declinecounter(self): + pass + + def publish(self): + self._record("VEVENT", True, True) + + def refresh(self): + self._record("VEVENT", True, True) + + def reply(self): + self._record("VEVENT", False, False) + + def request(self): + self._record("VEVENT", True, True) + +class Freebusy(PersonHandler): + + "A free/busy handler." + + def publish(self): + pass + + def reply(self): + pass + + def request(self): + pass + +class Journal(PersonHandler): + + "A journal entry handler." + + def add(self): + pass + + def cancel(self): + pass + + def publish(self): + self._record("VJOURNAL", True) + +class Todo(PersonHandler): + + "A to-do item handler." + + def add(self): + pass + + def cancel(self): + pass + + def counter(self): + pass + + def declinecounter(self): + pass + + def publish(self): + self._record("VTODO", True) + + def refresh(self): + self._record("VTODO", True) + + def reply(self): + self._record("VTODO", False) + + def request(self): + self._record("VTODO", True) + +# Handler registry. + +handlers = [ + ("VFREEBUSY", Freebusy), + ("VEVENT", Event), + ("VTODO", Todo), + ("VJOURNAL", Journal), + ] + +# vim: tabstop=4 expandtab shiftwidth=4