imip-agent

imiptools/content.py

1267:7819b77d9330
2017-09-15 Paul Boddie Introduced a tentative means of classifying periods for suitable operations upon updating an event.
     1 #!/usr/bin/env python     2      3 """     4 The handler invocation mechanism.     5      6 Copyright (C) 2014, 2015, 2017 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 settings    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 IMIP_COUNTER_AS_REQUEST = settings["IMIP_COUNTER_AS_REQUEST"]    31     32 def handle_itip_part(part, handlers):    33     34     """    35     Handle the given iTIP 'part' using the given 'handlers' dictionary.    36     37     Return a list of responses, each response being a tuple of the form    38     (outgoing-recipients, message-part).    39     """    40     41     method = part.get_param("method")    42     method = method and method.upper()    43     44     # Decode the data and parse it.    45     46     f = StringIO(part.get_payload(decode=True))    47     48     itip = parse_object(f, part.get_content_charset(), "VCALENDAR")    49     50     # Ignore the part if not a calendar object.    51     52     if not itip:    53         return    54     55     # Require consistency between declared and employed methods.    56     57     itip_method = get_value(itip, "METHOD")    58     59     if itip_method == method or \    60        IMIP_COUNTER_AS_REQUEST and itip_method == "COUNTER" and method == "REQUEST":    61     62         # Assert the object's method as the definitive one.    63     64         method = itip_method    65     66         # Look for different kinds of sections.    67     68         all_results = []    69     70         for name, items in itip.items():    71     72             # Get a handler for the given section.    73     74             handler = handlers.get(name)    75             if not handler:    76                 continue    77     78             for item in items:    79     80                 # Dispatch to a handler and obtain any response.    81     82                 handler.set_object(Object({name : item}))    83                 handler.set_identity(method)    84     85                 if handler.is_usable(method):    86     87                     # Perform the method in a critical section.    88     89                     handler.acquire_lock()    90                     try:    91                         methods[method](handler)()    92                     finally:    93                         handler.release_lock()    94     95 # Handler registry.    96     97 methods = {    98     "ADD"            : lambda handler: handler.add,    99     "CANCEL"         : lambda handler: handler.cancel,   100     "COUNTER"        : lambda handler: handler.counter,   101     "DECLINECOUNTER" : lambda handler: handler.declinecounter,   102     "PUBLISH"        : lambda handler: handler.publish,   103     "REFRESH"        : lambda handler: handler.refresh,   104     "REPLY"          : lambda handler: handler.reply,   105     "REQUEST"        : lambda handler: handler.request,   106     }   107    108 # vim: tabstop=4 expandtab shiftwidth=4