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