imip-agent

Annotated imiptools/client.py

466:8d2dfe43b629
2015-03-31 Paul Boddie Fixed free/busy period conversion to retain the original period instance types.
paul@441 1
#!/usr/bin/env python
paul@441 2
paul@441 3
"""
paul@441 4
Common calendar client utilities.
paul@441 5
paul@441 6
Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk>
paul@441 7
paul@441 8
This program is free software; you can redistribute it and/or modify it under
paul@441 9
the terms of the GNU General Public License as published by the Free Software
paul@441 10
Foundation; either version 3 of the License, or (at your option) any later
paul@441 11
version.
paul@441 12
paul@441 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@441 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@441 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@441 16
details.
paul@441 17
paul@441 18
You should have received a copy of the GNU General Public License along with
paul@441 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@441 20
"""
paul@441 21
paul@443 22
from imiptools.data import get_window_end, uri_items
paul@443 23
from imiptools.dates import get_default_timezone
paul@443 24
from imiptools.profile import Preferences
paul@441 25
paul@441 26
def update_attendees(obj, added, removed):
paul@441 27
paul@441 28
    """
paul@441 29
    Update the attendees in 'obj' with the given 'added' and 'removed'
paul@441 30
    attendee lists. A list is returned containing the attendees whose
paul@441 31
    attendance should be cancelled.
paul@441 32
    """
paul@441 33
paul@441 34
    to_cancel = []
paul@441 35
paul@441 36
    if added or removed:
paul@441 37
        attendees = uri_items(obj.get_items("ATTENDEE") or [])
paul@460 38
        sequence = obj.get_value("SEQUENCE")
paul@441 39
paul@441 40
        if removed:
paul@441 41
            remaining = []
paul@441 42
paul@441 43
            for attendee, attendee_attr in attendees:
paul@441 44
                if attendee in removed:
paul@460 45
paul@460 46
                    # Without a sequence number, assume that the event has not
paul@460 47
                    # been published and that attendees can be silently removed.
paul@460 48
paul@460 49
                    if sequence is not None:
paul@441 50
                        to_cancel.append((attendee, attendee_attr))
paul@441 51
                else:
paul@441 52
                    remaining.append((attendee, attendee_attr))
paul@441 53
paul@441 54
            attendees = remaining
paul@441 55
paul@441 56
        if added:
paul@441 57
            for attendee in added:
paul@441 58
                attendees.append((attendee, {"PARTSTAT" : "NEEDS-ACTION", "RSVP" : "TRUE"}))
paul@441 59
paul@441 60
        obj["ATTENDEE"] = attendees
paul@441 61
paul@441 62
    return to_cancel
paul@441 63
paul@443 64
class Client:
paul@443 65
paul@443 66
    "Common handler and manager methods."
paul@443 67
paul@443 68
    def __init__(self, user):
paul@443 69
        self.user = user
paul@443 70
        self.preferences = None
paul@443 71
paul@443 72
    def get_preferences(self):
paul@443 73
        if not self.preferences:
paul@443 74
            self.preferences = Preferences(self.user)
paul@443 75
        return self.preferences
paul@443 76
paul@443 77
    def get_tzid(self):
paul@443 78
        prefs = self.get_preferences()
paul@443 79
        return prefs.get("TZID") or get_default_timezone()
paul@443 80
paul@443 81
    def get_window_size(self):
paul@443 82
        prefs = self.get_preferences()
paul@443 83
        try:
paul@443 84
            return int(prefs.get("window_size"))
paul@443 85
        except (TypeError, ValueError):
paul@443 86
            return 100
paul@443 87
paul@443 88
    def get_window_end(self):
paul@443 89
        return get_window_end(self.get_tzid(), self.get_window_size())
paul@443 90
paul@443 91
    def is_sharing(self):
paul@443 92
        return self.get_preferences().get("freebusy_sharing") == "share" 
paul@443 93
paul@443 94
    def is_bundling(self):
paul@443 95
        return self.get_preferences().get("freebusy_bundling") == "always"
paul@443 96
paul@441 97
# vim: tabstop=4 expandtab shiftwidth=4