imip-agent

Annotated imiptools/content.py

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