imip-agent

Annotated imiptools/handlers/person_outgoing.py

146:367b6c1b82b0
2015-01-12 Paul Boddie Added copyright and licensing notices. Exposed a path configuration setting in the manager program.
paul@96 1
#!/usr/bin/env python
paul@96 2
paul@96 3
"""
paul@96 4
Handlers for a person for whom scheduling is performed, inspecting outgoing
paul@96 5
messages to obtain scheduling done externally.
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@96 21
"""
paul@96 22
paul@129 23
from imiptools.content import Handler, uri_item
paul@96 24
from vCalendar import to_node
paul@96 25
paul@96 26
class PersonHandler(Handler):
paul@96 27
paul@96 28
    "Handling mechanisms specific to people."
paul@96 29
paul@140 30
    def _get_identity(self, objtype, from_organiser=True):
paul@130 31
paul@140 32
        """
paul@140 33
        Get the identity of interest in a usable form for any unprocessed
paul@140 34
        object.
paul@140 35
        """
paul@130 36
paul@140 37
        identity, attr = item = uri_item(self.get_item(from_organiser and "ORGANIZER" or "ATTENDEE"))
paul@96 38
paul@97 39
        # Check for event using UID.
paul@97 40
paul@97 41
        if not self.have_new_object(identity, objtype):
paul@140 42
            return None
paul@140 43
paul@140 44
        return item
paul@140 45
paul@140 46
    def _record(self, objtype, from_organiser=True, update_freebusy=False):
paul@140 47
paul@140 48
        "Record free/busy and object information."
paul@140 49
paul@140 50
        item = self._get_identity(objtype, from_organiser)
paul@140 51
        if not item:
paul@99 52
            return False
paul@97 53
paul@140 54
        identity, attr = item
paul@140 55
paul@96 56
        # Store the object.
paul@96 57
paul@96 58
        self.store.set_event(identity, self.uid, to_node(
paul@96 59
            {objtype : [(self.details, {})]}
paul@96 60
            ))
paul@96 61
paul@96 62
        # Update free/busy information.
paul@96 63
paul@96 64
        if update_freebusy:
paul@97 65
paul@97 66
            # If newer than any old version, discard old details from the
paul@97 67
            # free/busy record and check for suitability.
paul@97 68
paul@96 69
            periods = self.get_periods()
paul@96 70
            freebusy = self.store.get_freebusy(identity) or []
paul@97 71
paul@126 72
            if from_organiser or attr.get("PARTSTAT") != "DECLINED":
paul@122 73
                self.update_freebusy(freebusy, identity, periods)
paul@122 74
            else:
paul@122 75
                self.remove_from_freebusy(freebusy, identity)
paul@97 76
paul@96 77
            if self.publisher:
paul@96 78
                self.publisher.set_freebusy(identity, freebusy)
paul@96 79
paul@96 80
        return True
paul@96 81
paul@140 82
    def _remove(self, objtype, from_organiser=True):
paul@140 83
paul@140 84
        "Remove free/busy information for any unprocessed object."
paul@140 85
paul@140 86
        item = self._get_identity(objtype, from_organiser)
paul@140 87
        if not item:
paul@140 88
            return False
paul@140 89
paul@140 90
        identity, attr = item
paul@140 91
paul@140 92
        freebusy = self.store.get_freebusy(identity) or []
paul@140 93
        self.remove_from_freebusy(freebusy, identity)
paul@140 94
paul@140 95
        return True
paul@140 96
paul@96 97
class Event(PersonHandler):
paul@96 98
paul@96 99
    "An event handler."
paul@96 100
paul@96 101
    def add(self):
paul@96 102
        pass
paul@96 103
paul@96 104
    def cancel(self):
paul@140 105
        self._remove("VEVENT", True)
paul@96 106
paul@96 107
    def counter(self):
paul@96 108
        pass
paul@96 109
paul@96 110
    def declinecounter(self):
paul@96 111
        pass
paul@96 112
paul@96 113
    def publish(self):
paul@96 114
        self._record("VEVENT", True, True)
paul@96 115
paul@96 116
    def refresh(self):
paul@96 117
        self._record("VEVENT", True, True)
paul@96 118
paul@96 119
    def reply(self):
paul@99 120
        self._record("VEVENT", False, True)
paul@96 121
paul@96 122
    def request(self):
paul@96 123
        self._record("VEVENT", True, True)
paul@96 124
paul@96 125
class Freebusy(PersonHandler):
paul@96 126
paul@96 127
    "A free/busy handler."
paul@96 128
paul@96 129
    def publish(self):
paul@96 130
        pass
paul@96 131
paul@96 132
    def reply(self):
paul@96 133
        pass
paul@96 134
paul@96 135
    def request(self):
paul@96 136
        pass
paul@96 137
paul@96 138
class Journal(PersonHandler):
paul@96 139
paul@96 140
    "A journal entry handler."
paul@96 141
paul@96 142
    def add(self):
paul@96 143
        pass
paul@96 144
paul@96 145
    def cancel(self):
paul@140 146
        self._remove("VJOURNAL", True)
paul@96 147
paul@96 148
    def publish(self):
paul@96 149
        self._record("VJOURNAL", True)
paul@96 150
paul@96 151
class Todo(PersonHandler):
paul@96 152
paul@96 153
    "A to-do item handler."
paul@96 154
paul@96 155
    def add(self):
paul@96 156
        pass
paul@96 157
paul@96 158
    def cancel(self):
paul@140 159
        self._remove("VTODO", True)
paul@96 160
paul@96 161
    def counter(self):
paul@96 162
        pass
paul@96 163
paul@96 164
    def declinecounter(self):
paul@96 165
        pass
paul@96 166
paul@96 167
    def publish(self):
paul@96 168
        self._record("VTODO", True)
paul@96 169
paul@96 170
    def refresh(self):
paul@96 171
        self._record("VTODO", True)
paul@96 172
paul@96 173
    def reply(self):
paul@96 174
        self._record("VTODO", False)
paul@96 175
paul@96 176
    def request(self):
paul@96 177
        self._record("VTODO", True)
paul@96 178
paul@96 179
# Handler registry.
paul@96 180
paul@96 181
handlers = [
paul@96 182
    ("VFREEBUSY",   Freebusy),
paul@96 183
    ("VEVENT",      Event),
paul@96 184
    ("VTODO",       Todo),
paul@96 185
    ("VJOURNAL",    Journal),
paul@96 186
    ]
paul@96 187
paul@96 188
# vim: tabstop=4 expandtab shiftwidth=4