imip-agent

Annotated imiptools/handlers/common.py

183:c6776371ecc8
2015-01-28 Paul Boddie Moved support code for free/busy publication into a separate class so that the person handler can use it without introducing a duplicate request method. Added free/busy publication upon receiving event invitations.
paul@108 1
#!/usr/bin/env python
paul@108 2
paul@108 3
"""
paul@108 4
Common handler functionality for different entities.
paul@146 5
paul@146 6
Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>
paul@146 7
paul@146 8
This program is free software; you can redistribute it and/or modify it under
paul@146 9
the terms of the GNU General Public License as published by the Free Software
paul@146 10
Foundation; either version 3 of the License, or (at your option) any later
paul@146 11
version.
paul@146 12
paul@146 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@146 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@146 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@146 16
details.
paul@146 17
paul@146 18
You should have received a copy of the GNU General Public License along with
paul@146 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@108 20
"""
paul@108 21
paul@108 22
from imiptools.content import to_part
paul@108 23
paul@183 24
class SupportFreebusy:
paul@108 25
paul@183 26
    "Support for free/busy publishing and sharing."
paul@181 27
paul@181 28
    def make_freebusy_to_publish(self, from_organiser=True):
paul@181 29
paul@181 30
        """
paul@181 31
        Make a freebusy object for publication for a user, providing either an
paul@181 32
        organiser's details if 'from_organiser' is set to a true value, or an
paul@181 33
        attendee's details otherwise.
paul@181 34
        """
paul@181 35
paul@181 36
        calendar = self.make_freebusy(from_organiser, publish=True)
paul@181 37
paul@181 38
        # Return a published object.
paul@181 39
paul@182 40
        return [(True, to_part("PUBLISH", calendar))]
paul@181 41
paul@181 42
    def make_freebusy(self, from_organiser=True, publish=False):
paul@181 43
paul@181 44
        """
paul@181 45
        Make a freebusy object, providing either an organiser's details if
paul@181 46
        'from_organiser' is set to a true value, or an attendee's details
paul@181 47
        otherwise.
paul@181 48
        """
paul@181 49
paul@108 50
        oa = self.require_organiser_and_attendees()
paul@108 51
        if not oa:
paul@108 52
            return None
paul@108 53
paul@181 54
        (organiser, organiser_attr), attendees = oa
paul@108 55
paul@181 56
        # Get the details for each attendee.
paul@108 57
paul@108 58
        calendar = []
paul@108 59
        cwrite = calendar.append
paul@108 60
paul@181 61
        for attendee, attendee_attr in attendees.items():
paul@108 62
paul@181 63
            # Construct an appropriate fragment.
paul@181 64
paul@181 65
            freebusy = self.store.get_freebusy(from_organiser and organiser or attendee)
paul@108 66
paul@108 67
            record = []
paul@108 68
            rwrite = record.append
paul@108 69
paul@181 70
            # For replies, the organiser is preserved.
paul@181 71
paul@181 72
            if not publish or from_organiser:
paul@181 73
                rwrite(("ORGANIZER", organiser_attr, organiser))
paul@181 74
paul@181 75
            # For published objects, the organiser is actually the user whose
paul@181 76
            # information is being provided.
paul@181 77
paul@181 78
            else:
paul@181 79
                rwrite(("ORGANIZER", attendee_attr, attendee))
paul@181 80
paul@181 81
            # For replies, the attendee is preserved.
paul@181 82
            # (Published objects do not employ the attendee property.)
paul@181 83
paul@181 84
            if not publish:
paul@181 85
                rwrite(("ATTENDEE", attendee_attr, attendee))
paul@181 86
paul@108 87
            rwrite(("UID", {}, self.uid))
paul@108 88
paul@108 89
            if freebusy:
paul@112 90
                for start, end, uid, transp in freebusy:
paul@112 91
                    if transp == "OPAQUE":
paul@112 92
                        rwrite(("FREEBUSY", {"FBTYPE" : "BUSY"}, "/".join([start, end])))
paul@108 93
paul@108 94
            cwrite(("VFREEBUSY", {}, record))
paul@108 95
paul@181 96
        # Return the object.
paul@108 97
paul@181 98
        return calendar
paul@108 99
paul@183 100
class CommonFreebusy(SupportFreebusy):
paul@183 101
paul@183 102
    "Common free/busy mix-in."
paul@183 103
paul@183 104
    def request(self):
paul@183 105
paul@183 106
        """
paul@183 107
        Respond to a request by preparing a reply containing free/busy
paul@183 108
        information for each indicated attendee.
paul@183 109
        """
paul@183 110
paul@183 111
        calendar = self.make_freebusy(from_organiser=False)
paul@183 112
paul@183 113
        # Return the reply.
paul@183 114
paul@183 115
        return [(True, to_part("REPLY", calendar))]
paul@183 116
paul@108 117
# vim: tabstop=4 expandtab shiftwidth=4