summaryrefslogtreecommitdiffstats
path: root/pykolab/xml/recurrence_rule.py
blob: a82fec7e241424a25b14f17ee419d1289c8557c6 (plain)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
import icalendar
import datetime
import kolabformat
from pykolab.xml import utils as xmlutils

from pykolab.translate import _
from pykolab.translate import N_

"""
    def setFrequency(self, *args): return _kolabformat.RecurrenceRule_setFrequency(self, *args)
    def frequency(self): return _kolabformat.RecurrenceRule_frequency(self)
    def setWeekStart(self, *args): return _kolabformat.RecurrenceRule_setWeekStart(self, *args)
    def weekStart(self): return _kolabformat.RecurrenceRule_weekStart(self)
    def setEnd(self, *args): return _kolabformat.RecurrenceRule_setEnd(self, *args)
    def end(self): return _kolabformat.RecurrenceRule_end(self)
    def setCount(self, *args): return _kolabformat.RecurrenceRule_setCount(self, *args)
    def count(self): return _kolabformat.RecurrenceRule_count(self)
    def setInterval(self, *args): return _kolabformat.RecurrenceRule_setInterval(self, *args)
    def interval(self): return _kolabformat.RecurrenceRule_interval(self)
    def setBysecond(self, *args): return _kolabformat.RecurrenceRule_setBysecond(self, *args)
    def bysecond(self): return _kolabformat.RecurrenceRule_bysecond(self)
    def setByminute(self, *args): return _kolabformat.RecurrenceRule_setByminute(self, *args)
    def byminute(self): return _kolabformat.RecurrenceRule_byminute(self)
    def setByhour(self, *args): return _kolabformat.RecurrenceRule_setByhour(self, *args)
    def byhour(self): return _kolabformat.RecurrenceRule_byhour(self)
    def setByday(self, *args): return _kolabformat.RecurrenceRule_setByday(self, *args)
    def byday(self): return _kolabformat.RecurrenceRule_byday(self)
    def setBymonthday(self, *args): return _kolabformat.RecurrenceRule_setBymonthday(self, *args)
    def bymonthday(self): return _kolabformat.RecurrenceRule_bymonthday(self)
    def setByyearday(self, *args): return _kolabformat.RecurrenceRule_setByyearday(self, *args)
    def byyearday(self): return _kolabformat.RecurrenceRule_byyearday(self)
    def setByweekno(self, *args): return _kolabformat.RecurrenceRule_setByweekno(self, *args)
    def byweekno(self): return _kolabformat.RecurrenceRule_byweekno(self)
    def setBymonth(self, *args): return _kolabformat.RecurrenceRule_setBymonth(self, *args)
    def bymonth(self): return _kolabformat.RecurrenceRule_bymonth(self)
    def isValid(self): return _kolabformat.RecurrenceRule_isValid(self)
"""

frequency_labels = {
    "YEARLY":   N_("Every %d year(s)"),
    "MONTHLY":  N_("Every %d month(s)"),
    "WEEKLY":   N_("Every %d week(s)"),
    "DAILY":    N_("Every %d day(s)"),
    "HOURLY":   N_("Every %d hours"),
    "MINUTELY": N_("Every %d minutes"),
    "SECONDLY": N_("Every %d seconds")
}

def frequency_label(freq):
    return _(frequency_labels[freq]) if frequency_labels.has_key(freq) else _(freq)


class RecurrenceRule(kolabformat.RecurrenceRule):
    frequency_map = {
        None: kolabformat.RecurrenceRule.FreqNone,
        "YEARLY": kolabformat.RecurrenceRule.Yearly,
        "MONTHLY": kolabformat.RecurrenceRule.Monthly,
        "WEEKLY": kolabformat.RecurrenceRule.Weekly,
        "DAILY": kolabformat.RecurrenceRule.Daily,
        "HOURLY": kolabformat.RecurrenceRule.Hourly,
        "MINUTELY": kolabformat.RecurrenceRule.Minutely,
        "SECONDLY": kolabformat.RecurrenceRule.Secondly
    }

    weekday_map = {
        "MO": kolabformat.Monday,
        "TU": kolabformat.Tuesday,
        "WE": kolabformat.Wednesday,
        "TH": kolabformat.Thursday,
        "FR": kolabformat.Friday,
        "SA": kolabformat.Saturday,
        "SU": kolabformat.Sunday
    }

    properties_map = {
        'freq': 'get_frequency',
        'interval':  'interval',
        'count':     'count',
        'until':     'end',
        'bymonth':   'bymonth',
        'byday':     'byday',
        'bymonthday':'bymonthday',
        'byyearday': 'byyearday',
        'byweekno':  'byweekno',
        'byhour':    'byhour',
        'byminute':  'byminute',
        'wkst':      'get_weekstart'
    }

    def __init__(self, rrule=None):
        if rrule == None:
            kolabformat.RecurrenceRule.__init__(self)
        else:
            kolabformat.RecurrenceRule.__init__(self, rrule)

    def from_ical(self, vrecur):
        vectorimap = {
            'BYSECOND': 'setBysecond',
            'BYMINUTE': 'setByminute',
            'BYHOUR': 'setByhour',
            'BYMONTHDAY': 'setBymonthday',
            'BYYEARDAY': 'setByyearday',
            'BYMONTH': 'setBymonth',
        }

        settermap = {
            'FREQ': 'set_frequency',
            'INTERVAL': 'set_interval',
            'COUNT': 'set_count',
            'UNTIL': 'set_until',
            'WKST': 'set_weekstart',
            'BYDAY': 'set_byday',
        }

        for prop,setter in vectorimap.items():
            if vrecur.has_key(prop):
                getattr(self, setter)([int(v) for v in vrecur[prop]])

        for prop,setter in settermap.items():
            if vrecur.has_key(prop):
                getattr(self, setter)(vrecur[prop])

    def set_count(self, count):
        if isinstance(count, list):
            count = count[0]
        self.setCount(int(count))

    def set_interval(self, val):
        if isinstance(val, list):
            val = val[0]
        self.setInterval(int(val))

    def set_frequency(self, freq):
        self._set_map_value(freq, self.frequency_map, 'setFrequency')

    def get_frequency(self, translated=False):
        freq = self.frequency()
        if translated:
            return self._translate_value(freq, self.frequency_map)
        return freq

    def set_byday(self, bdays):
        daypos = kolabformat.vectordaypos()
        for wday in bdays:
            weekday = str(wday)[-2:]
            occurrence = int(wday.relative)
            if str(wday)[0] == '-':
                occurrence = occurrence * -1
            if self.weekday_map.has_key(weekday):
                daypos.append(kolabformat.DayPos(occurrence, self.weekday_map[weekday]))
        self.setByday(daypos)

    def set_weekstart(self, wkst):
        self._set_map_value(wkst, self.weekday_map, 'setWeekStart')

    def get_weekstart(self, translated=False):
        wkst = self.weekStart()
        if translated:
            return self._translate_value(wkst, self.weekday_map)
        return wkst

    def set_until(self, until):
        if isinstance(until, list):
            until = until[0]
        if isinstance(until, datetime.datetime) or isinstance(until, datetime.date):
            self.setEnd(xmlutils.to_cdatetime(until, True))

    def _set_map_value(self, val, pmap, setter):
        if isinstance(val, list):
            val = val[0]
        if val in pmap.keys():
            getattr(self, setter)(pmap[val])
        elif val in pmap.values():
            getattr(self, setter)(val)

    def _translate_value(self, val, map):
        name_map = dict([(v, k) for (k, v) in map.iteritems()])
        return name_map[val] if name_map.has_key(val) else 'UNKNOWN'

    def to_dict(self):
        if not self.isValid() or self.frequency() == kolabformat.RecurrenceRule.FreqNone:
            return None

        data = dict()

        for p, getter in self.properties_map.iteritems():
            val = None
            args = {}
            if hasattr(self, getter):
                if getter.startswith('get_'):
                    args = dict(translated=True)
            if hasattr(self, getter):
                val = getattr(self, getter)(**args)
            if isinstance(val, kolabformat.cDateTime):
                val = xmlutils.from_cdatetime(val, True)
            elif isinstance(val, kolabformat.vectori):
                val = ",".join([int(v) for x in val])
            elif isinstance(val, kolabformat.vectordaypos):
                val = ",".join(["%s%s" % (str(x.occurence()) if x.occurence() != 0 else '', self._translate_value(x.weekday(), self.weekday_map)) for x in val])
            if val is not None:
                data[p] = val

        return data