aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py')
-rwxr-xr-xlib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py1097
1 files changed, 0 insertions, 1097 deletions
diff --git a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py b/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py
deleted file mode 100755
index 6bd83cad..00000000
--- a/lib/python2.7/site-packages/python_dateutil-1.5-py2.7.egg/dateutil/rrule.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-"""
-Copyright (c) 2003-2010 Gustavo Niemeyer <gustavo@niemeyer.net>
-
-This module offers extensions to the standard python 2.3+
-datetime module.
-"""
-__author__ = "Gustavo Niemeyer <gustavo@niemeyer.net>"
-__license__ = "PSF License"
-
-import itertools
-import datetime
-import calendar
-import thread
-import sys
-
-__all__ = ["rrule", "rruleset", "rrulestr",
- "YEARLY", "MONTHLY", "WEEKLY", "DAILY",
- "HOURLY", "MINUTELY", "SECONDLY",
- "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
-
-# Every mask is 7 days longer to handle cross-year weekly periods.
-M366MASK = tuple([1]*31+[2]*29+[3]*31+[4]*30+[5]*31+[6]*30+
- [7]*31+[8]*31+[9]*30+[10]*31+[11]*30+[12]*31+[1]*7)
-M365MASK = list(M366MASK)
-M29, M30, M31 = range(1,30), range(1,31), range(1,32)
-MDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
-MDAY365MASK = list(MDAY366MASK)
-M29, M30, M31 = range(-29,0), range(-30,0), range(-31,0)
-NMDAY366MASK = tuple(M31+M29+M31+M30+M31+M30+M31+M31+M30+M31+M30+M31+M31[:7])
-NMDAY365MASK = list(NMDAY366MASK)
-M366RANGE = (0,31,60,91,121,152,182,213,244,274,305,335,366)
-M365RANGE = (0,31,59,90,120,151,181,212,243,273,304,334,365)
-WDAYMASK = [0,1,2,3,4,5,6]*55
-del M29, M30, M31, M365MASK[59], MDAY365MASK[59], NMDAY365MASK[31]
-MDAY365MASK = tuple(MDAY365MASK)
-M365MASK = tuple(M365MASK)
-
-(YEARLY,
- MONTHLY,
- WEEKLY,
- DAILY,
- HOURLY,
- MINUTELY,
- SECONDLY) = range(7)
-
-# Imported on demand.
-easter = None
-parser = None
-
-class weekday(object):
- __slots__ = ["weekday", "n"]
-
- def __init__(self, weekday, n=None):
- if n == 0:
- raise ValueError, "Can't create weekday with n == 0"
- self.weekday = weekday
- self.n = n
-
- def __call__(self, n):
- if n == self.n:
- return self
- else:
- return self.__class__(self.weekday, n)
-
- def __eq__(self, other):
- try:
- if self.weekday != other.weekday or self.n != other.n:
- return False
- except AttributeError:
- return False
- return True
-
- def __repr__(self):
- s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
- if not self.n:
- return s
- else:
- return "%s(%+d)" % (s, self.n)
-
-MO, TU, WE, TH, FR, SA, SU = weekdays = tuple([weekday(x) for x in range(7)])
-
-class rrulebase:
- def __init__(self, cache=False):
- if cache:
- self._cache = []
- self._cache_lock = thread.allocate_lock()
- self._cache_gen = self._iter()
- self._cache_complete = False
- else:
- self._cache = None
- self._cache_complete = False
- self._len = None
-
- def __iter__(self):
- if self._cache_complete:
- return iter(self._cache)
- elif self._cache is None:
- return self._iter()
- else:
- return self._iter_cached()
-
- def _iter_cached(self):
- i = 0
- gen = self._cache_gen
- cache = self._cache
- acquire = self._cache_lock.acquire
- release = self._cache_lock.release
- while gen:
- if i == len(cache):
- acquire()
- if self._cache_complete:
- break
- try:
- for j in range(10):
- cache.append(gen.next())
- except StopIteration:
- self._cache_gen = gen = None
- self._cache_complete = True
- break
- release()
- yield cache[i]
- i += 1
- while i < self._len:
- yield cache[i]
- i += 1
-
- def __getitem__(self, item):
- if self._cache_complete:
- return self._cache[item]
- elif isinstance(item, slice):
- if item.step and item.step < 0:
- return list(iter(self))[item]
- else:
- return list(itertools.islice(self,
- item.start or 0,
- item.stop or sys.maxint,
- item.step or 1))
- elif item >= 0:
- gen = iter(self)
- try:
- for i in range(item+1):
- res = gen.next()
- except StopIteration:
- raise IndexError
- return res
- else:
- return list(iter(self))[item]
-
- def __contains__(self, item):
- if self._cache_complete:
- return item in self._cache
- else:
- for i in self:
- if i == item:
- return True
- elif i > item:
- return False
- return False
-
- # __len__() introduces a large performance penality.
- def count(self):
- if self._len is None:
- for x in self: pass
- return self._len
-
- def before(self, dt, inc=False):
- if self._cache_complete:
- gen = self._cache
- else:
- gen = self
- last = None
- if inc:
- for i in gen:
- if i > dt:
- break
- last = i
- else:
- for i in gen:
- if i >= dt:
- break
- last = i
- return last
-
- def after(self, dt, inc=False):
- if self._cache_complete:
- gen = self._cache
- else:
- gen = self
- if inc:
- for i in gen:
- if i >= dt:
- return i
- else:
- for i in gen:
- if i > dt:
- return i
- return None
-
- def between(self, after, before, inc=False):
- if self._cache_complete:
- gen = self._cache
- else:
- gen = self
- started = False
- l = []
- if inc:
- for i in gen:
- if i > before:
- break
- elif not started:
- if i >= after:
- started = True
- l.append(i)
- else:
- l.append(i)
- else:
- for i in gen:
- if i >= before:
- break
- elif not started:
- if i > after:
- started = True
- l.append(i)
- else:
- l.append(i)
- return l
-
-class rrule(rrulebase):
- def __init__(self, freq, dtstart=None,
- interval=1, wkst=None, count=None, until=None, bysetpos=None,
- bymonth=None, bymonthday=None, byyearday=None, byeaster=None,
- byweekno=None, byweekday=None,
- byhour=None, byminute=None, bysecond=None,
- cache=False):
- rrulebase.__init__(self, cache)
- global easter
- if not dtstart:
- dtstart = datetime.datetime.now().replace(microsecond=0)
- elif not isinstance(dtstart, datetime.datetime):
- dtstart = datetime.datetime.fromordinal(dtstart.toordinal())
- else:
- dtstart = dtstart.replace(microsecond=0)
- self._dtstart = dtstart
- self._tzinfo = dtstart.tzinfo
- self._freq = freq
- self._interval = interval
- self._count = count
- if until and not isinstance(until, datetime.datetime):
- until = datetime.datetime.fromordinal(until.toordinal())
- self._until = until
- if wkst is None:
- self._wkst = calendar.firstweekday()
- elif type(wkst) is int:
- self._wkst = wkst
- else:
- self._wkst = wkst.weekday
- if bysetpos is None:
- self._bysetpos = None
- elif type(bysetpos) is int:
- if bysetpos == 0 or not (-366 <= bysetpos <= 366):
- raise ValueError("bysetpos must be between 1 and 366, "
- "or between -366 and -1")
- self._bysetpos = (bysetpos,)
- else:
- self._bysetpos = tuple(bysetpos)
- for pos in self._bysetpos:
- if pos == 0 or not (-366 <= pos <= 366):
- raise ValueError("bysetpos must be between 1 and 366, "
- "or between -366 and -1")
- if not (byweekno or byyearday or bymonthday or
- byweekday is not None or byeaster is not None):
- if freq == YEARLY:
- if not bymonth:
- bymonth = dtstart.month
- bymonthday = dtstart.day
- elif freq == MONTHLY:
- bymonthday = dtstart.day
- elif freq == WEEKLY:
- byweekday = dtstart.weekday()
- # bymonth
- if not bymonth:
- self._bymonth = None
- elif type(bymonth) is int:
- self._bymonth = (bymonth,)
- else:
- self._bymonth = tuple(bymonth)
- # byyearday
- if not byyearday:
- self._byyearday = None
- elif type(byyearday) is int:
- self._byyearday = (byyearday,)
- else:
- self._byyearday = tuple(byyearday)
- # byeaster
- if byeaster is not None:
- if not easter:
- from dateutil import easter
- if type(byeaster) is int:
- self._byeaster = (byeaster,)
- else:
- self._byeaster = tuple(byeaster)
- else:
- self._byeaster = None
- # bymonthay
- if not bymonthday:
- self._bymonthday = ()
- self._bynmonthday = ()
- elif type(bymonthday) is int:
- if bymonthday < 0:
- self._bynmonthday = (bymonthday,)
- self._bymonthday = ()
- else:
- self._bymonthday = (bymonthday,)
- self._bynmonthday = ()
- else:
- self._bymonthday = tuple([x for x in bymonthday if x > 0])
- self._bynmonthday = tuple([x for x in bymonthday if x < 0])
- # byweekno
- if byweekno is None:
- self._byweekno = None
- elif type(byweekno) is int:
- self._byweekno = (byweekno,)
- else:
- self._byweekno = tuple(byweekno)
- # byweekday / bynweekday
- if byweekday is None:
- self._byweekday = None
- self._bynweekday = None
- elif type(byweekday) is int:
- self._byweekday = (byweekday,)
- self._bynweekday = None
- elif hasattr(byweekday, "n"):
- if not byweekday.n or freq > MONTHLY:
- self._byweekday = (byweekday.weekday,)
- self._bynweekday = None
- else:
- self._bynweekday = ((byweekday.weekday, byweekday.n),)
- self._byweekday = None
- else:
- self._byweekday = []
- self._bynweekday = []
- for wday in byweekday:
- if type(wday) is int:
- self._byweekday.append(wday)
- elif not wday.n or freq > MONTHLY:
- self._byweekday.append(wday.weekday)
- else:
- self._bynweekday.append((wday.weekday, wday.n))
- self._byweekday = tuple(self._byweekday)
- self._bynweekday = tuple(self._bynweekday)
- if not self._byweekday:
- self._byweekday = None
- elif not self._bynweekday:
- self._bynweekday = None
- # byhour
- if byhour is None:
- if freq < HOURLY:
- self._byhour = (dtstart.hour,)
- else:
- self._byhour = None
- elif type(byhour) is int:
- self._byhour = (byhour,)
- else:
- self._byhour = tuple(byhour)
- # byminute
- if byminute is None:
- if freq < MINUTELY:
- self._byminute = (dtstart.minute,)
- else:
- self._byminute = None
- elif type(byminute) is int:
- self._byminute = (byminute,)
- else:
- self._byminute = tuple(byminute)
- # bysecond
- if bysecond is None:
- if freq < SECONDLY:
- self._bysecond = (dtstart.second,)
- else:
- self._bysecond = None
- elif type(bysecond) is int:
- self._bysecond = (bysecond,)
- else:
- self._bysecond = tuple(bysecond)
-
- if self._freq >= HOURLY:
- self._timeset = None
- else:
- self._timeset = []
- for hour in self._byhour:
- for minute in self._byminute:
- for second in self._bysecond:
- self._timeset.append(
- datetime.time(hour, minute, second,
- tzinfo=self._tzinfo))
- self._timeset.sort()
- self._timeset = tuple(self._timeset)
-
- def _iter(self):
- year, month, day, hour, minute, second, weekday, yearday, _ = \
- self._dtstart.timetuple()
-
- # Some local variables to speed things up a bit
- freq = self._freq
- interval = self._interval
- wkst = self._wkst
- until = self._until
- bymonth = self._bymonth
- byweekno = self._byweekno
- byyearday = self._byyearday
- byweekday = self._byweekday
- byeaster = self._byeaster
- bymonthday = self._bymonthday
- bynmonthday = self._bynmonthday
- bysetpos = self._bysetpos
- byhour = self._byhour
- byminute = self._byminute
- bysecond = self._bysecond
-
- ii = _iterinfo(self)
- ii.rebuild(year, month)
-
- getdayset = {YEARLY:ii.ydayset,
- MONTHLY:ii.mdayset,
- WEEKLY:ii.wdayset,
- DAILY:ii.ddayset,
- HOURLY:ii.ddayset,
- MINUTELY:ii.ddayset,
- SECONDLY:ii.ddayset}[freq]
-
- if freq < HOURLY:
- timeset = self._timeset
- else:
- gettimeset = {HOURLY:ii.htimeset,
- MINUTELY:ii.mtimeset,
- SECONDLY:ii.stimeset}[freq]
- if ((freq >= HOURLY and
- self._byhour and hour not in self._byhour) or
- (freq >= MINUTELY and
- self._byminute and minute not in self._byminute) or
- (freq >= SECONDLY and
- self._bysecond and second not in self._bysecond)):
- timeset = ()
- else:
- timeset = gettimeset(hour, minute, second)
-
- total = 0
- count = self._count
- while True:
- # Get dayset with the right frequency
- dayset, start, end = getdayset(year, month, day)
-
- # Do the "hard" work ;-)
- filtered = False
- for i in dayset[start:end]:
- if ((bymonth and ii.mmask[i] not in bymonth) or
- (byweekno and not ii.wnomask[i]) or
- (byweekday and ii.wdaymask[i] not in byweekday) or
- (ii.nwdaymask and not ii.nwdaymask[i]) or
- (byeaster and not ii.eastermask[i]) or
- ((bymonthday or bynmonthday) and
- ii.mdaymask[i] not in bymonthday and
- ii.nmdaymask[i] not in bynmonthday) or
- (byyearday and
- ((i < ii.yearlen and i+1 not in byyearday
- and -ii.yearlen+i not in byyearday) or
- (i >= ii.yearlen and i+1-ii.yearlen not in byyearday
- and -ii.nextyearlen+i-ii.yearlen
- not in byyearday)))):
- dayset[i] = None
- filtered = True
-
- # Output results
- if bysetpos and timeset:
- poslist = []
- for pos in bysetpos:
- if pos < 0:
- daypos, timepos = divmod(pos, len(timeset))
- else:
- daypos, timepos = divmod(pos-1, len(timeset))
- try:
- i = [x for x in dayset[start:end]
- if x is not None][daypos]
- time = timeset[timepos]
- except IndexError:
- pass
- else:
- date = datetime.date.fromordinal(ii.yearordinal+i)
- res = datetime.datetime.combine(date, time)
- if res not in poslist:
- poslist.append(res)
- poslist.sort()
- for res in poslist:
- if until and res > until:
- self._len = total
- return
- elif res >= self._dtstart:
- total += 1
- yield res
- if count:
- count -= 1
- if not count:
- self._len = total
- return
- else:
- for i in dayset[start:end]:
- if i is not None:
- date = datetime.date.fromordinal(ii.yearordinal+i)
- for time in timeset:
- res = datetime.datetime.combine(date, time)
- if until and res > until:
- self._len = total
- return
- elif res >= self._dtstart:
- total += 1
- yield res
- if count:
- count -= 1
- if not count:
- self._len = total
- return
-
- # Handle frequency and interval
- fixday = False
- if freq == YEARLY:
- year += interval
- if year > datetime.MAXYEAR:
- self._len = total
- return
- ii.rebuild(year, month)
- elif freq == MONTHLY:
- month += interval
- if month > 12:
- div, mod = divmod(month, 12)
- month = mod
- year += div
- if month == 0:
- month = 12
- year -= 1
- if year > datetime.MAXYEAR:
- self._len = total
- return
- ii.rebuild(year, month)
- elif freq == WEEKLY:
- if wkst > weekday:
- day += -(weekday+1+(6-wkst))+self._interval*7
- else:
- day += -(weekday-wkst)+self._interval*7
- weekday = wkst
- fixday = True
- elif freq == DAILY:
- day += interval
- fixday = True
- elif freq == HOURLY:
- if filtered:
- # Jump to one iteration before next day
- hour += ((23-hour)//interval)*interval
- while True:
- hour += interval
- div, mod = divmod(hour, 24)
- if div:
- hour = mod
- day += div
- fixday = True
- if not byhour or hour in byhour:
- break
- timeset = gettimeset(hour, minute, second)
- elif freq == MINUTELY:
- if filtered:
- # Jump to one iteration before next day
- minute += ((1439-(hour*60+minute))//interval)*interval
- while True:
- minute += interval
- div, mod = divmod(minute, 60)
- if div:
- minute = mod
- hour += div
- div, mod = divmod(hour, 24)
- if div:
- hour = mod
- day += div
- fixday = True
- filtered = False
- if ((not byhour or hour in byhour) and
- (not byminute or minute in byminute)):
- break
- timeset = gettimeset(hour, minute, second)
- elif freq == SECONDLY:
- if filtered:
- # Jump to one iteration before next day
- second += (((86399-(hour*3600+minute*60+second))
- //interval)*interval)
- while True:
- second += self._interval
- div, mod = divmod(second, 60)
- if div:
- second = mod
- minute += div
- div, mod = divmod(minute, 60)
- if div:
- minute = mod
- hour += div
- div, mod = divmod(hour, 24)
- if div:
- hour = mod
- day += div
- fixday = True
- if ((not byhour or hour in byhour) and
- (not byminute or minute in byminute) and
- (not bysecond or second in bysecond)):
- break
- timeset = gettimeset(hour, minute, second)
-
- if fixday and day > 28:
- daysinmonth = calendar.monthrange(year, month)[1]
- if day > daysinmonth:
- while day > daysinmonth:
- day -= daysinmonth
- month += 1
- if month == 13:
- month = 1
- year += 1
- if year > datetime.MAXYEAR:
- self._len = total
- return
- daysinmonth = calendar.monthrange(year, month)[1]
- ii.rebuild(year, month)
-
-class _iterinfo(object):
- __slots__ = ["rrule", "lastyear", "lastmonth",
- "yearlen", "nextyearlen", "yearordinal", "yearweekday",
- "mmask", "mrange", "mdaymask", "nmdaymask",
- "wdaymask", "wnomask", "nwdaymask", "eastermask"]
-
- def __init__(self, rrule):
- for attr in self.__slots__:
- setattr(self, attr, None)
- self.rrule = rrule
-
- def rebuild(self, year, month):
- # Every mask is 7 days longer to handle cross-year weekly periods.
- rr = self.rrule
- if year != self.lastyear:
- self.yearlen = 365+calendar.isleap(year)
- self.nextyearlen = 365+calendar.isleap(year+1)
- firstyday = datetime.date(year, 1, 1)
- self.yearordinal = firstyday.toordinal()
- self.yearweekday = firstyday.weekday()
-
- wday = datetime.date(year, 1, 1).weekday()
- if self.yearlen == 365:
- self.mmask = M365MASK
- self.mdaymask = MDAY365MASK
- self.nmdaymask = NMDAY365MASK
- self.wdaymask = WDAYMASK[wday:]
- self.mrange = M365RANGE
- else:
- self.mmask = M366MASK
- self.mdaymask = MDAY366MASK
- self.nmdaymask = NMDAY366MASK
- self.wdaymask = WDAYMASK[wday:]
- self.mrange = M366RANGE
-
- if not rr._byweekno:
- self.wnomask = None
- else:
- self.wnomask = [0]*(self.yearlen+7)
- #no1wkst = firstwkst = self.wdaymask.index(rr._wkst)
- no1wkst = firstwkst = (7-self.yearweekday+rr._wkst)%7
- if no1wkst >= 4:
- no1wkst = 0
- # Number of days in the year, plus the days we got
- # from last year.
- wyearlen = self.yearlen+(self.yearweekday-rr._wkst)%7
- else:
- # Number of days in the year, minus the days we
- # left in last year.
- wyearlen = self.yearlen-no1wkst
- div, mod = divmod(wyearlen, 7)
- numweeks = div+mod//4
- for n in rr._byweekno:
- if n < 0:
- n += numweeks+1
- if not (0 < n <= numweeks):
- continue
- if n > 1:
- i = no1wkst+(n-1)*7
- if no1wkst != firstwkst:
- i -= 7-firstwkst
- else:
- i = no1wkst
- for j in range(7):
- self.wnomask[i] = 1
- i += 1
- if self.wdaymask[i] == rr._wkst:
- break
- if 1 in rr._byweekno:
- # Check week number 1 of next year as well
- # TODO: Check -numweeks for next year.
- i = no1wkst+numweeks*7
- if no1wkst != firstwkst:
- i -= 7-firstwkst
- if i < self.yearlen:
- # If week starts in next year, we
- # don't care about it.
- for j in range(7):
- self.wnomask[i] = 1
- i += 1
- if self.wdaymask[i] == rr._wkst:
- break
- if no1wkst:
- # Check last week number of last year as
- # well. If no1wkst is 0, either the year
- # started on week start, or week number 1
- # got days from last year, so there are no
- # days from last year's last week number in
- # this year.
- if -1 not in rr._byweekno:
- lyearweekday = datetime.date(year-1,1,1).weekday()
- lno1wkst = (7-lyearweekday+rr._wkst)%7
- lyearlen = 365+calendar.isleap(year-1)
- if lno1wkst >= 4:
- lno1wkst = 0
- lnumweeks = 52+(lyearlen+
- (lyearweekday-rr._wkst)%7)%7//4
- else:
- lnumweeks = 52+(self.yearlen-no1wkst)%7//4
- else:
- lnumweeks = -1
- if lnumweeks in rr._byweekno:
- for i in range(no1wkst):
- self.wnomask[i] = 1
-
- if (rr._bynweekday and
- (month != self.lastmonth or year != self.lastyear)):
- ranges = []
- if rr._freq == YEARLY:
- if rr._bymonth:
- for month in rr._bymonth:
- ranges.append(self.mrange[month-1:month+1])
- else:
- ranges = [(0, self.yearlen)]
- elif rr._freq == MONTHLY:
- ranges = [self.mrange[month-1:month+1]]
- if ranges:
- # Weekly frequency won't get here, so we may not
- # care about cross-year weekly periods.
- self.nwdaymask = [0]*self.yearlen
- for first, last in ranges:
- last -= 1
- for wday, n in rr._bynweekday:
- if n < 0:
- i = last+(n+1)*7
- i -= (self.wdaymask[i]-wday)%7
- else:
- i = first+(n-1)*7
- i += (7-self.wdaymask[i]+wday)%7
- if first <= i <= last:
- self.nwdaymask[i] = 1
-
- if rr._byeaster:
- self.eastermask = [0]*(self.yearlen+7)
- eyday = easter.easter(year).toordinal()-self.yearordinal
- for offset in rr._byeaster:
- self.eastermask[eyday+offset] = 1
-
- self.lastyear = year
- self.lastmonth = month
-
- def ydayset(self, year, month, day):
- return range(self.yearlen), 0, self.yearlen
-
- def mdayset(self, year, month, day):
- set = [None]*self.yearlen
- start, end = self.mrange[month-1:month+1]
- for i in range(start, end):
- set[i] = i
- return set, start, end
-
- def wdayset(self, year, month, day):
- # We need to handle cross-year weeks here.
- set = [None]*(self.yearlen+7)
- i = datetime.date(year, month, day).toordinal()-self.yearordinal
- start = i
- for j in range(7):
- set[i] = i
- i += 1
- #if (not (0 <= i < self.yearlen) or
- # self.wdaymask[i] == self.rrule._wkst):
- # This will cross the year boundary, if necessary.
- if self.wdaymask[i] == self.rrule._wkst:
- break
- return set, start, i
-
- def ddayset(self, year, month, day):
- set = [None]*self.yearlen
- i = datetime.date(year, month, day).toordinal()-self.yearordinal
- set[i] = i
- return set, i, i+1
-
- def htimeset(self, hour, minute, second):
- set = []
- rr = self.rrule
- for minute in rr._byminute:
- for second in rr._bysecond:
- set.append(datetime.time(hour, minute, second,
- tzinfo=rr._tzinfo))
- set.sort()
- return set
-
- def mtimeset(self, hour, minute, second):
- set = []
- rr = self.rrule
- for second in rr._bysecond:
- set.append(datetime.time(hour, minute, second, tzinfo=rr._tzinfo))
- set.sort()
- return set
-
- def stimeset(self, hour, minute, second):
- return (datetime.time(hour, minute, second,
- tzinfo=self.rrule._tzinfo),)
-
-
-class rruleset(rrulebase):
-
- class _genitem:
- def __init__(self, genlist, gen):
- try:
- self.dt = gen()
- genlist.append(self)
- except StopIteration:
- pass
- self.genlist = genlist
- self.gen = gen
-
- def next(self):
- try:
- self.dt = self.gen()
- except StopIteration:
- self.genlist.remove(self)
-
- def __cmp__(self, other):
- return cmp(self.dt, other.dt)
-
- def __init__(self, cache=False):
- rrulebase.__init__(self, cache)
- self._rrule = []
- self._rdate = []
- self._exrule = []
- self._exdate = []
-
- def rrule(self, rrule):
- self._rrule.append(rrule)
-
- def rdate(self, rdate):
- self._rdate.append(rdate)
-
- def exrule(self, exrule):
- self._exrule.append(exrule)
-
- def exdate(self, exdate):
- self._exdate.append(exdate)
-
- def _iter(self):
- rlist = []
- self._rdate.sort()
- self._genitem(rlist, iter(self._rdate).next)
- for gen in [iter(x).next for x in self._rrule]:
- self._genitem(rlist, gen)
- rlist.sort()
- exlist = []
- self._exdate.sort()
- self._genitem(exlist, iter(self._exdate).next)
- for gen in [iter(x).next for x in self._exrule]:
- self._genitem(exlist, gen)
- exlist.sort()
- lastdt = None
- total = 0
- while rlist:
- ritem = rlist[0]
- if not lastdt or lastdt != ritem.dt:
- while exlist and exlist[0] < ritem:
- exlist[0].next()
- exlist.sort()
- if not exlist or ritem != exlist[0]:
- total += 1
- yield ritem.dt
- lastdt = ritem.dt
- ritem.next()
- rlist.sort()
- self._len = total
-
-class _rrulestr:
-
- _freq_map = {"YEARLY": YEARLY,
- "MONTHLY": MONTHLY,
- "WEEKLY": WEEKLY,
- "DAILY": DAILY,
- "HOURLY": HOURLY,
- "MINUTELY": MINUTELY,
- "SECONDLY": SECONDLY}
-
- _weekday_map = {"MO":0,"TU":1,"WE":2,"TH":3,"FR":4,"SA":5,"SU":6}
-
- def _handle_int(self, rrkwargs, name, value, **kwargs):
- rrkwargs[name.lower()] = int(value)
-
- def _handle_int_list(self, rrkwargs, name, value, **kwargs):
- rrkwargs[name.lower()] = [int(x) for x in value.split(',')]
-
- _handle_INTERVAL = _handle_int
- _handle_COUNT = _handle_int
- _handle_BYSETPOS = _handle_int_list
- _handle_BYMONTH = _handle_int_list
- _handle_BYMONTHDAY = _handle_int_list
- _handle_BYYEARDAY = _handle_int_list
- _handle_BYEASTER = _handle_int_list
- _handle_BYWEEKNO = _handle_int_list
- _handle_BYHOUR = _handle_int_list
- _handle_BYMINUTE = _handle_int_list
- _handle_BYSECOND = _handle_int_list
-
- def _handle_FREQ(self, rrkwargs, name, value, **kwargs):
- rrkwargs["freq"] = self._freq_map[value]
-
- def _handle_UNTIL(self, rrkwargs, name, value, **kwargs):
- global parser
- if not parser:
- from dateutil import parser
- try:
- rrkwargs["until"] = parser.parse(value,
- ignoretz=kwargs.get("ignoretz"),
- tzinfos=kwargs.get("tzinfos"))
- except ValueError:
- raise ValueError, "invalid until date"
-
- def _handle_WKST(self, rrkwargs, name, value, **kwargs):
- rrkwargs["wkst"] = self._weekday_map[value]
-
- def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg):
- l = []
- for wday in value.split(','):
- for i in range(len(wday)):
- if wday[i] not in '+-0123456789':
- break
- n = wday[:i] or None
- w = wday[i:]
- if n: n = int(n)
- l.append(weekdays[self._weekday_map[w]](n))
- rrkwargs["byweekday"] = l
-
- _handle_BYDAY = _handle_BYWEEKDAY
-
- def _parse_rfc_rrule(self, line,
- dtstart=None,
- cache=False,
- ignoretz=False,
- tzinfos=None):
- if line.find(':') != -1:
- name, value = line.split(':')
- if name != "RRULE":
- raise ValueError, "unknown parameter name"
- else:
- value = line
- rrkwargs = {}
- for pair in value.split(';'):
- name, value = pair.split('=')
- name = name.upper()
- value = value.upper()
- try:
- getattr(self, "_handle_"+name)(rrkwargs, name, value,
- ignoretz=ignoretz,
- tzinfos=tzinfos)
- except AttributeError:
- raise ValueError, "unknown parameter '%s'" % name
- except (KeyError, ValueError):
- raise ValueError, "invalid '%s': %s" % (name, value)
- return rrule(dtstart=dtstart, cache=cache, **rrkwargs)
-
- def _parse_rfc(self, s,
- dtstart=None,
- cache=False,
- unfold=False,
- forceset=False,
- compatible=False,
- ignoretz=False,
- tzinfos=None):
- global parser
- if compatible:
- forceset = True
- unfold = True
- s = s.upper()
- if not s.strip():
- raise ValueError, "empty string"
- if unfold:
- lines = s.splitlines()
- i = 0
- while i < len(lines):
- line = lines[i].rstrip()
- if not line:
- del lines[i]
- elif i > 0 and line[0] == " ":
- lines[i-1] += line[1:]
- del lines[i]
- else:
- i += 1
- else:
- lines = s.split()
- if (not forceset and len(lines) == 1 and
- (s.find(':') == -1 or s.startswith('RRULE:'))):
- return self._parse_rfc_rrule(lines[0], cache=cache,
- dtstart=dtstart, ignoretz=ignoretz,
- tzinfos=tzinfos)
- else:
- rrulevals = []
- rdatevals = []
- exrulevals = []
- exdatevals = []
- for line in lines:
- if not line:
- continue
- if line.find(':') == -1:
- name = "RRULE"
- value = line
- else:
- name, value = line.split(':', 1)
- parms = name.split(';')
- if not parms:
- raise ValueError, "empty property name"
- name = parms[0]
- parms = parms[1:]
- if name == "RRULE":
- for parm in parms:
- raise ValueError, "unsupported RRULE parm: "+parm
- rrulevals.append(value)
- elif name == "RDATE":
- for parm in parms:
- if parm != "VALUE=DATE-TIME":
- raise ValueError, "unsupported RDATE parm: "+parm
- rdatevals.append(value)
- elif name == "EXRULE":
- for parm in parms:
- raise ValueError, "unsupported EXRULE parm: "+parm
- exrulevals.append(value)
- elif name == "EXDATE":
- for parm in parms:
- if parm != "VALUE=DATE-TIME":
- raise ValueError, "unsupported RDATE parm: "+parm
- exdatevals.append(value)
- elif name == "DTSTART":
- for parm in parms:
- raise ValueError, "unsupported DTSTART parm: "+parm
- if not parser:
- from dateutil import parser
- dtstart = parser.parse(value, ignoretz=ignoretz,
- tzinfos=tzinfos)
- else:
- raise ValueError, "unsupported property: "+name
- if (forceset or len(rrulevals) > 1 or
- rdatevals or exrulevals or exdatevals):
- if not parser and (rdatevals or exdatevals):
- from dateutil import parser
- set = rruleset(cache=cache)
- for value in rrulevals:
- set.rrule(self._parse_rfc_rrule(value, dtstart=dtstart,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- for value in rdatevals:
- for datestr in value.split(','):
- set.rdate(parser.parse(datestr,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- for value in exrulevals:
- set.exrule(self._parse_rfc_rrule(value, dtstart=dtstart,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- for value in exdatevals:
- for datestr in value.split(','):
- set.exdate(parser.parse(datestr,
- ignoretz=ignoretz,
- tzinfos=tzinfos))
- if compatible and dtstart:
- set.rdate(dtstart)
- return set
- else:
- return self._parse_rfc_rrule(rrulevals[0],
- dtstart=dtstart,
- cache=cache,
- ignoretz=ignoretz,
- tzinfos=tzinfos)
-
- def __call__(self, s, **kwargs):
- return self._parse_rfc(s, **kwargs)
-
-rrulestr = _rrulestr()
-
-# vim:ts=4:sw=4:et