imip-agent

imiptools/content.py

1063:67369fd525db
2016-03-03 Paul Boddie Introduced a common free/busy collection abstraction and a specific database collection class. freebusy-collections
     1 #!/usr/bin/env python     2      3 """     4 The handler invocation mechanism.     5      6 Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20 """    21     22 from imiptools.config import IMIP_COUNTER_AS_REQUEST    23 from imiptools.data import Object, parse_object, get_value    24     25 try:    26     from cStringIO import StringIO    27 except ImportError:    28     from StringIO import StringIO    29     30 def handle_itip_part(part, handlers):    31     32     """    33     Handle the given iTIP 'part' using the given 'handlers' dictionary.    34     35     Return a list of responses, each response being a tuple of the form    36     (outgoing-recipients, message-part).    37     """    38     39     method = part.get_param("method")    40     method = method and method.upper()    41     42     # Decode the data and parse it.    43     44     f = StringIO(part.get_payload(decode=True))    45     46     itip = parse_object(f, part.get_content_charset(), "VCALENDAR")    47     48     # Ignore the part if not a calendar object.    49     50     if not itip:    51         return    52     53     # Require consistency between declared and employed methods.    54     55     itip_method = get_value(itip, "METHOD")    56     57     if itip_method == method or \    58        IMIP_COUNTER_AS_REQUEST and itip_method == "COUNTER" and method == "REQUEST":    59     60         # Assert the object's method as the definitive one.    61     62         method = itip_method    63     64         # Look for different kinds of sections.    65     66         all_results = []    67     68         for name, items in itip.items():    69     70             # Get a handler for the given section.    71     72             handler = handlers.get(name)    73             if not handler:    74                 continue    75     76             for item in items:    77     78                 # Dispatch to a handler and obtain any response.    79     80                 handler.set_object(Object({name : item}))    81                 handler.set_identity(method)    82     83                 if handler.is_usable(method):    84     85                     # Perform the method in a critical section.    86     87                     handler.acquire_lock()    88                     try:    89                         methods[method](handler)()    90                     finally:    91                         handler.release_lock()    92     93 # Handler registry.    94     95 methods = {    96     "ADD"            : lambda handler: handler.add,    97     "CANCEL"         : lambda handler: handler.cancel,    98     "COUNTER"        : lambda handler: handler.counter,    99     "DECLINECOUNTER" : lambda handler: handler.declinecounter,   100     "PUBLISH"        : lambda handler: handler.publish,   101     "REFRESH"        : lambda handler: handler.refresh,   102     "REPLY"          : lambda handler: handler.reply,   103     "REQUEST"        : lambda handler: handler.request,   104     }   105    106 # vim: tabstop=4 expandtab shiftwidth=4