home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_2371 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  29.0 KB  |  1,225 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __author__ = 'Gustavo Niemeyer <gustavo@niemeyer.net>'
  5. __license__ = 'PSF License'
  6. import itertools
  7. import datetime
  8. import calendar
  9. import thread
  10. import sys
  11. __all__ = [
  12.     'rrule',
  13.     'rruleset',
  14.     'rrulestr',
  15.     'YEARLY',
  16.     'MONTHLY',
  17.     'WEEKLY',
  18.     'DAILY',
  19.     'HOURLY',
  20.     'MINUTELY',
  21.     'SECONDLY',
  22.     'MO',
  23.     'TU',
  24.     'WE',
  25.     'TH',
  26.     'FR',
  27.     'SA',
  28.     'SU']
  29. M366MASK = tuple([
  30.     1] * 31 + [
  31.     2] * 29 + [
  32.     3] * 31 + [
  33.     4] * 30 + [
  34.     5] * 31 + [
  35.     6] * 30 + [
  36.     7] * 31 + [
  37.     8] * 31 + [
  38.     9] * 30 + [
  39.     10] * 31 + [
  40.     11] * 30 + [
  41.     12] * 31 + [
  42.     1] * 7)
  43. M365MASK = list(M366MASK)
  44. (M29, M30, M31) = (range(1, 30), range(1, 31), range(1, 32))
  45. MDAY366MASK = tuple(M31 + M29 + M31 + M30 + M31 + M30 + M31 + M31 + M30 + M31 + M30 + M31 + M31[:7])
  46. MDAY365MASK = list(MDAY366MASK)
  47. (M29, M30, M31) = (range(-29, 0), range(-30, 0), range(-31, 0))
  48. NMDAY366MASK = tuple(M31 + M29 + M31 + M30 + M31 + M30 + M31 + M31 + M30 + M31 + M30 + M31 + M31[:7])
  49. NMDAY365MASK = list(NMDAY366MASK)
  50. M366RANGE = (0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366)
  51. M365RANGE = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365)
  52. WDAYMASK = [
  53.     0,
  54.     1,
  55.     2,
  56.     3,
  57.     4,
  58.     5,
  59.     6] * 55
  60. del M29
  61. del M30
  62. del M31
  63. del M365MASK[59]
  64. del MDAY365MASK[59]
  65. del NMDAY365MASK[31]
  66. MDAY365MASK = tuple(MDAY365MASK)
  67. M365MASK = tuple(M365MASK)
  68. (YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY) = range(7)
  69. easter = None
  70. parser = None
  71.  
  72. class weekday(object):
  73.     __slots__ = [
  74.         'weekday',
  75.         'n']
  76.     
  77.     def __init__(self, weekday, n = None):
  78.         if n == 0:
  79.             raise ValueError, "Can't create weekday with n == 0"
  80.         n == 0
  81.         self.weekday = weekday
  82.         self.n = n
  83.  
  84.     
  85.     def __call__(self, n):
  86.         if n == self.n:
  87.             return self
  88.         return self.__class__(self.weekday, n)
  89.  
  90.     
  91.     def __eq__(self, other):
  92.         
  93.         try:
  94.             if self.weekday != other.weekday or self.n != other.n:
  95.                 return False
  96.         except AttributeError:
  97.             return False
  98.  
  99.         return True
  100.  
  101.     
  102.     def __repr__(self):
  103.         s = ('MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU')[self.weekday]
  104.         if not self.n:
  105.             return s
  106.         return '%s(%+d)' % (s, self.n)
  107.  
  108.  
  109.  
  110. class rrulebase:
  111.     
  112.     def __init__(self, cache = False):
  113.         if cache:
  114.             self._cache = []
  115.             self._cache_lock = thread.allocate_lock()
  116.             self._cache_gen = self._iter()
  117.             self._cache_complete = False
  118.         else:
  119.             self._cache = None
  120.             self._cache_complete = False
  121.         self._len = None
  122.  
  123.     
  124.     def __iter__(self):
  125.         if self._cache_complete:
  126.             return iter(self._cache)
  127.         if self._cache is None:
  128.             return self._iter()
  129.         return self._iter_cached()
  130.  
  131.     
  132.     def _iter_cached(self):
  133.         i = 0
  134.         gen = self._cache_gen
  135.         cache = self._cache
  136.         acquire = self._cache_lock.acquire
  137.         release = self._cache_lock.release
  138.         while gen:
  139.             if i == len(cache):
  140.                 acquire()
  141.                 if self._cache_complete:
  142.                     break
  143.                 
  144.                 
  145.                 try:
  146.                     for j in range(10):
  147.                         cache.append(gen.next())
  148.                 except StopIteration:
  149.                     self._cache_gen = None
  150.                     gen = None
  151.                     self._cache_complete = True
  152.                     break
  153.  
  154.                 release()
  155.             
  156.             yield cache[i]
  157.             i += 1
  158.         while i < self._len:
  159.             yield cache[i]
  160.             i += 1
  161.  
  162.     
  163.     def __getitem__(self, item):
  164.         if self._cache_complete:
  165.             return self._cache[item]
  166.         if isinstance(item, slice):
  167.             if item.step and item.step < 0:
  168.                 return list(iter(self))[item]
  169.             if not item.start:
  170.                 pass
  171.             if not item.stop:
  172.                 pass
  173.             if not item.step:
  174.                 pass
  175.             return list(itertools.islice(self, 0, sys.maxint, 1))
  176.         isinstance(item, slice)
  177.         if item >= 0:
  178.             gen = iter(self)
  179.             
  180.             try:
  181.                 for i in range(item + 1):
  182.                     res = gen.next()
  183.             except StopIteration:
  184.                 self._cache_complete
  185.                 self._cache_complete
  186.                 raise IndexError
  187.             except:
  188.                 self._cache_complete
  189.  
  190.             return res
  191.         return list(iter(self))[item]
  192.  
  193.     
  194.     def __contains__(self, item):
  195.         if self._cache_complete:
  196.             return item in self._cache
  197.         for i in self:
  198.             if i == item:
  199.                 return True
  200.             if i > item:
  201.                 return False
  202.         
  203.         return False
  204.  
  205.     
  206.     def count(self):
  207.         if self._len is None:
  208.             for x in self:
  209.                 pass
  210.             
  211.         
  212.         return self._len
  213.  
  214.     
  215.     def before(self, dt, inc = False):
  216.         if self._cache_complete:
  217.             gen = self._cache
  218.         else:
  219.             gen = self
  220.         last = None
  221.         if inc:
  222.             for i in gen:
  223.                 if i > dt:
  224.                     break
  225.                 
  226.                 last = i
  227.             
  228.         else:
  229.             for i in gen:
  230.                 if i >= dt:
  231.                     break
  232.                 
  233.                 last = i
  234.             
  235.         return last
  236.  
  237.     
  238.     def after(self, dt, inc = False):
  239.         if self._cache_complete:
  240.             gen = self._cache
  241.         else:
  242.             gen = self
  243.  
  244.     
  245.     def between(self, after, before, inc = False):
  246.         if self._cache_complete:
  247.             gen = self._cache
  248.         else:
  249.             gen = self
  250.         started = False
  251.         l = []
  252.         if inc:
  253.             for i in gen:
  254.                 if i > before:
  255.                     break
  256.                     continue
  257.                 if not started:
  258.                     if i >= after:
  259.                         started = True
  260.                         l.append(i)
  261.                     
  262.                 i >= after
  263.                 l.append(i)
  264.             
  265.         else:
  266.             for i in gen:
  267.                 if i >= before:
  268.                     break
  269.                     continue
  270.                 if not started:
  271.                     if i > after:
  272.                         started = True
  273.                         l.append(i)
  274.                     
  275.                 i > after
  276.                 l.append(i)
  277.             
  278.         return l
  279.  
  280.  
  281.  
  282. class rrule(rrulebase):
  283.     
  284.     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):
  285.         global easter
  286.         rrulebase.__init__(self, cache)
  287.         if not dtstart:
  288.             dtstart = datetime.datetime.now().replace(microsecond = 0)
  289.         elif not isinstance(dtstart, datetime.datetime):
  290.             dtstart = datetime.datetime.fromordinal(dtstart.toordinal())
  291.         else:
  292.             dtstart = dtstart.replace(microsecond = 0)
  293.         self._dtstart = dtstart
  294.         self._tzinfo = dtstart.tzinfo
  295.         self._freq = freq
  296.         self._interval = interval
  297.         self._count = count
  298.         if until and not isinstance(until, datetime.datetime):
  299.             until = datetime.datetime.fromordinal(until.toordinal())
  300.         
  301.         self._until = until
  302.         if wkst is None:
  303.             self._wkst = calendar.firstweekday()
  304.         elif type(wkst) is int:
  305.             self._wkst = wkst
  306.         else:
  307.             self._wkst = wkst.weekday
  308.         if bysetpos is None:
  309.             self._bysetpos = None
  310.         elif type(bysetpos) is int:
  311.             if bysetpos == 0 or not None if bysetpos <= bysetpos else bysetpos <= 366:
  312.                 raise ValueError('bysetpos must be between 1 and 366, or between -366 and -1')
  313.             not None if bysetpos <= bysetpos else bysetpos <= 366
  314.             self._bysetpos = (bysetpos,)
  315.         else:
  316.             self._bysetpos = tuple(bysetpos)
  317.             for pos in self._bysetpos:
  318.                 if pos == 0 or not None if pos <= pos else pos <= 366:
  319.                     raise ValueError('bysetpos must be between 1 and 366, or between -366 and -1')
  320.                 not None if pos <= pos else pos <= 366
  321.             
  322.         if not byweekno and byyearday and bymonthday and byweekday is not None or byeaster is not None:
  323.             if freq == YEARLY:
  324.                 if not bymonth:
  325.                     bymonth = dtstart.month
  326.                 
  327.                 bymonthday = dtstart.day
  328.             elif freq == MONTHLY:
  329.                 bymonthday = dtstart.day
  330.             elif freq == WEEKLY:
  331.                 byweekday = dtstart.weekday()
  332.             
  333.         
  334.         if not bymonth:
  335.             self._bymonth = None
  336.         elif type(bymonth) is int:
  337.             self._bymonth = (bymonth,)
  338.         else:
  339.             self._bymonth = tuple(bymonth)
  340.         if not byyearday:
  341.             self._byyearday = None
  342.         elif type(byyearday) is int:
  343.             self._byyearday = (byyearday,)
  344.         else:
  345.             self._byyearday = tuple(byyearday)
  346.         if byeaster is not None:
  347.             if not easter:
  348.                 easter = easter
  349.                 import dateutil
  350.             
  351.             if type(byeaster) is int:
  352.                 self._byeaster = (byeaster,)
  353.             else:
  354.                 self._byeaster = tuple(byeaster)
  355.         else:
  356.             self._byeaster = None
  357.         if not bymonthday:
  358.             self._bymonthday = ()
  359.             self._bynmonthday = ()
  360.         elif type(bymonthday) is int:
  361.             if bymonthday < 0:
  362.                 self._bynmonthday = (bymonthday,)
  363.                 self._bymonthday = ()
  364.             else:
  365.                 self._bymonthday = (bymonthday,)
  366.                 self._bynmonthday = ()
  367.         else:
  368.             self._bymonthday = [](_[1])
  369.             self._bynmonthday = [](_[2])
  370.         if byweekno is None:
  371.             self._byweekno = None
  372.         elif type(byweekno) is int:
  373.             self._byweekno = (byweekno,)
  374.         else:
  375.             self._byweekno = tuple(byweekno)
  376.         if byweekday is None:
  377.             self._byweekday = None
  378.             self._bynweekday = None
  379.         elif type(byweekday) is int:
  380.             self._byweekday = (byweekday,)
  381.             self._bynweekday = None
  382.         elif hasattr(byweekday, 'n'):
  383.             if not (byweekday.n) or freq > MONTHLY:
  384.                 self._byweekday = (byweekday.weekday,)
  385.                 self._bynweekday = None
  386.             else:
  387.                 self._bynweekday = ((byweekday.weekday, byweekday.n),)
  388.                 self._byweekday = None
  389.         else:
  390.             self._byweekday = []
  391.             self._bynweekday = []
  392.             for wday in byweekday:
  393.                 if type(wday) is int:
  394.                     self._byweekday.append(wday)
  395.                     continue
  396.                 if not (wday.n) or freq > MONTHLY:
  397.                     self._byweekday.append(wday.weekday)
  398.                     continue
  399.                 self._bynweekday.append((wday.weekday, wday.n))
  400.             
  401.             self._byweekday = tuple(self._byweekday)
  402.             self._bynweekday = tuple(self._bynweekday)
  403.             if not self._byweekday:
  404.                 self._byweekday = None
  405.             elif not self._bynweekday:
  406.                 self._bynweekday = None
  407.             
  408.         if byhour is None:
  409.             if freq < HOURLY:
  410.                 self._byhour = (dtstart.hour,)
  411.             else:
  412.                 self._byhour = None
  413.         elif type(byhour) is int:
  414.             self._byhour = (byhour,)
  415.         else:
  416.             self._byhour = tuple(byhour)
  417.         if byminute is None:
  418.             if freq < MINUTELY:
  419.                 self._byminute = (dtstart.minute,)
  420.             else:
  421.                 self._byminute = None
  422.         elif type(byminute) is int:
  423.             self._byminute = (byminute,)
  424.         else:
  425.             self._byminute = tuple(byminute)
  426.         if bysecond is None:
  427.             if freq < SECONDLY:
  428.                 self._bysecond = (dtstart.second,)
  429.             else:
  430.                 self._bysecond = None
  431.         elif type(bysecond) is int:
  432.             self._bysecond = (bysecond,)
  433.         else:
  434.             self._bysecond = tuple(bysecond)
  435.         if self._freq >= HOURLY:
  436.             self._timeset = None
  437.         else:
  438.             self._timeset = []
  439.             for hour in self._byhour:
  440.                 for minute in self._byminute:
  441.                     for second in self._bysecond:
  442.                         self._timeset.append(datetime.time(hour, minute, second, tzinfo = self._tzinfo))
  443.                     
  444.                 
  445.             
  446.             self._timeset.sort()
  447.             self._timeset = tuple(self._timeset)
  448.  
  449.     
  450.     def _iter(self):
  451.         (year, month, day, hour, minute, second, weekday, yearday, _) = self._dtstart.timetuple()
  452.         freq = self._freq
  453.         interval = self._interval
  454.         wkst = self._wkst
  455.         until = self._until
  456.         bymonth = self._bymonth
  457.         byweekno = self._byweekno
  458.         byyearday = self._byyearday
  459.         byweekday = self._byweekday
  460.         byeaster = self._byeaster
  461.         bymonthday = self._bymonthday
  462.         bynmonthday = self._bynmonthday
  463.         bysetpos = self._bysetpos
  464.         byhour = self._byhour
  465.         byminute = self._byminute
  466.         bysecond = self._bysecond
  467.         ii = _iterinfo(self)
  468.         ii.rebuild(year, month)
  469.         getdayset = {
  470.             YEARLY: ii.ydayset,
  471.             MONTHLY: ii.mdayset,
  472.             WEEKLY: ii.wdayset,
  473.             DAILY: ii.ddayset,
  474.             HOURLY: ii.ddayset,
  475.             MINUTELY: ii.ddayset,
  476.             SECONDLY: ii.ddayset }[freq]
  477.         if freq < HOURLY:
  478.             timeset = self._timeset
  479.         else:
  480.             gettimeset = {
  481.                 HOURLY: ii.htimeset,
  482.                 MINUTELY: ii.mtimeset,
  483.                 SECONDLY: ii.stimeset }[freq]
  484.             if not freq >= HOURLY and self._byhour or hour not in self._byhour:
  485.                 if (freq >= MINUTELY and self._byminute or minute not in self._byminute or freq >= SECONDLY) and self._bysecond and minute not in self._bysecond:
  486.                     timeset = ()
  487.                 else:
  488.                     timeset = gettimeset(hour, minute, second)
  489.         total = 0
  490.         count = self._count
  491.         while True:
  492.             (dayset, start, end) = getdayset(year, month, day)
  493.             filtered = False
  494.             for i in dayset[start:end]:
  495.                 if not bymonth or ii.mmask[i] not in bymonth:
  496.                     if not byweekno or not ii.wnomask[i]:
  497.                         if not byweekday or ii.wdaymask[i] not in byweekday:
  498.                             if not ii.nwdaymask or not ii.nwdaymask[i]:
  499.                                 if not byeaster or not ii.eastermask[i]:
  500.                                     if (bymonthday or bynmonthday) and ii.mdaymask[i] not in bymonthday or ii.nmdaymask[i] not in bynmonthday or byyearday:
  501.                                         if (i < ii.yearlen and i + 1 not in byyearday or -(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:
  502.                                             dayset[i] = None
  503.                                             filtered = True
  504.                                             continue
  505.             
  506.             if bysetpos and timeset:
  507.                 poslist = []
  508.                 for pos in bysetpos:
  509.                     if pos < 0:
  510.                         (daypos, timepos) = divmod(pos, len(timeset))
  511.                     else:
  512.                         (daypos, timepos) = divmod(pos - 1, len(timeset))
  513.                     
  514.                     try:
  515.                         i = _[1][daypos]
  516.                         time = timeset[timepos]
  517.                     except IndexError:
  518.                         continue
  519.  
  520.                     date = datetime.date.fromordinal(ii.yearordinal + i)
  521.                     res = datetime.datetime.combine(date, time)
  522.                     if res not in poslist:
  523.                         poslist.append(res)
  524.                         continue
  525.                 
  526.                 poslist.sort()
  527.                 for res in poslist:
  528.                     if until and res > until:
  529.                         self._len = total
  530.                         return None
  531.                     if res >= self._dtstart:
  532.                         total += 1
  533.                         yield res
  534.                         res > until
  535.                         if count:
  536.                             count -= 1
  537.                             if not count:
  538.                                 self._len = total
  539.                                 return None
  540.                         
  541.                     count
  542.                 
  543.             else:
  544.                 for i in dayset[start:end]:
  545.                     if i is not None:
  546.                         date = datetime.date.fromordinal(ii.yearordinal + i)
  547.                         for time in timeset:
  548.                             res = datetime.datetime.combine(date, time)
  549.                             if until and res > until:
  550.                                 self._len = total
  551.                                 return None
  552.                             if res >= self._dtstart:
  553.                                 total += 1
  554.                                 yield res
  555.                                 res > until
  556.                                 if count:
  557.                                     count -= 1
  558.                                     if not count:
  559.                                         self._len = total
  560.                                         return None
  561.                                 
  562.                             count
  563.                         
  564.                 
  565.             fixday = False
  566.             if freq == YEARLY:
  567.                 year += interval
  568.                 if year > datetime.MAXYEAR:
  569.                     self._len = total
  570.                     return None
  571.                 ii.rebuild(year, month)
  572.             elif freq == MONTHLY:
  573.                 month += interval
  574.                 if month > 12:
  575.                     (div, mod) = divmod(month, 12)
  576.                     month = mod
  577.                     year += div
  578.                     if month == 0:
  579.                         month = 12
  580.                         year -= 1
  581.                     
  582.                     if year > datetime.MAXYEAR:
  583.                         self._len = total
  584.                         return None
  585.                 
  586.                 ii.rebuild(year, month)
  587.             elif freq == WEEKLY:
  588.                 if wkst > weekday:
  589.                     day += -(weekday + 1 + (6 - wkst)) + self._interval * 7
  590.                 else:
  591.                     day += -(weekday - wkst) + self._interval * 7
  592.                 weekday = wkst
  593.                 fixday = True
  594.             elif freq == DAILY:
  595.                 day += interval
  596.                 fixday = True
  597.             elif freq == HOURLY:
  598.                 if filtered:
  599.                     hour += ((23 - hour) // interval) * interval
  600.                 
  601.                 while True:
  602.                     hour += interval
  603.                     (div, mod) = divmod(hour, 24)
  604.                     if div:
  605.                         hour = mod
  606.                         day += div
  607.                         fixday = True
  608.                     
  609.                     if not byhour or hour in byhour:
  610.                         break
  611.                         continue
  612.                 timeset = gettimeset(hour, minute, second)
  613.             elif freq == MINUTELY:
  614.                 if filtered:
  615.                     minute += ((1439 - (hour * 60 + minute)) // interval) * interval
  616.                 
  617.                 while True:
  618.                     minute += interval
  619.                     (div, mod) = divmod(minute, 60)
  620.                     if div:
  621.                         minute = mod
  622.                         hour += div
  623.                         (div, mod) = divmod(hour, 24)
  624.                         if div:
  625.                             hour = mod
  626.                             day += div
  627.                             fixday = True
  628.                             filtered = False
  629.                         
  630.                     
  631.                     if not byhour or hour in byhour:
  632.                         if not byminute or minute in byminute:
  633.                             break
  634.                             continue
  635.                 timeset = gettimeset(hour, minute, second)
  636.             elif freq == SECONDLY:
  637.                 if filtered:
  638.                     second += ((86399 - (hour * 3600 + minute * 60 + second)) // interval) * interval
  639.                 
  640.                 while True:
  641.                     second += self._interval
  642.                     (div, mod) = divmod(second, 60)
  643.                     if div:
  644.                         second = mod
  645.                         minute += div
  646.                         (div, mod) = divmod(minute, 60)
  647.                         if div:
  648.                             minute = mod
  649.                             hour += div
  650.                             (div, mod) = divmod(hour, 24)
  651.                             if div:
  652.                                 hour = mod
  653.                                 day += div
  654.                                 fixday = True
  655.                             
  656.                         
  657.                     
  658.                     if not byhour or hour in byhour:
  659.                         if not byminute or minute in byminute:
  660.                             if not bysecond or second in bysecond:
  661.                                 break
  662.                                 continue
  663.                 timeset = gettimeset(hour, minute, second)
  664.             
  665.             if fixday and day > 28:
  666.                 daysinmonth = calendar.monthrange(year, month)[1]
  667.                 if day > daysinmonth:
  668.                     while day > daysinmonth:
  669.                         day -= daysinmonth
  670.                         month += 1
  671.                         if month == 13:
  672.                             month = 1
  673.                             year += 1
  674.                             if year > datetime.MAXYEAR:
  675.                                 self._len = total
  676.                                 return None
  677.                         
  678.                         daysinmonth = calendar.monthrange(year, month)[1]
  679.                     ii.rebuild(year, month)
  680.                 
  681.             day > daysinmonth
  682.  
  683.  
  684.  
  685. class _iterinfo(object):
  686.     __slots__ = [
  687.         'rrule',
  688.         'lastyear',
  689.         'lastmonth',
  690.         'yearlen',
  691.         'nextyearlen',
  692.         'yearordinal',
  693.         'yearweekday',
  694.         'mmask',
  695.         'mrange',
  696.         'mdaymask',
  697.         'nmdaymask',
  698.         'wdaymask',
  699.         'wnomask',
  700.         'nwdaymask',
  701.         'eastermask']
  702.     
  703.     def __init__(self, rrule):
  704.         for attr in self.__slots__:
  705.             setattr(self, attr, None)
  706.         
  707.         self.rrule = rrule
  708.  
  709.     
  710.     def rebuild(self, year, month):
  711.         rr = self.rrule
  712.         if year != self.lastyear:
  713.             self.yearlen = 365 + calendar.isleap(year)
  714.             self.nextyearlen = 365 + calendar.isleap(year + 1)
  715.             firstyday = datetime.date(year, 1, 1)
  716.             self.yearordinal = firstyday.toordinal()
  717.             self.yearweekday = firstyday.weekday()
  718.             wday = datetime.date(year, 1, 1).weekday()
  719.             if self.yearlen == 365:
  720.                 self.mmask = M365MASK
  721.                 self.mdaymask = MDAY365MASK
  722.                 self.nmdaymask = NMDAY365MASK
  723.                 self.wdaymask = WDAYMASK[wday:]
  724.                 self.mrange = M365RANGE
  725.             else:
  726.                 self.mmask = M366MASK
  727.                 self.mdaymask = MDAY366MASK
  728.                 self.nmdaymask = NMDAY366MASK
  729.                 self.wdaymask = WDAYMASK[wday:]
  730.                 self.mrange = M366RANGE
  731.             if not rr._byweekno:
  732.                 self.wnomask = None
  733.             else:
  734.                 self.wnomask = [
  735.                     0] * (self.yearlen + 7)
  736.                 no1wkst = firstwkst = ((7 - self.yearweekday) + rr._wkst) % 7
  737.                 if no1wkst >= 4:
  738.                     no1wkst = 0
  739.                     wyearlen = self.yearlen + (self.yearweekday - rr._wkst) % 7
  740.                 else:
  741.                     wyearlen = self.yearlen - no1wkst
  742.                 (div, mod) = divmod(wyearlen, 7)
  743.                 numweeks = div + mod // 4
  744.                 for n in rr._byweekno:
  745.                     if n < 0:
  746.                         n += numweeks + 1
  747.                     
  748.                     if n < n:
  749.                         pass
  750.                     elif not n <= numweeks:
  751.                         continue
  752.                     
  753.                     if n > 1:
  754.                         i = no1wkst + (n - 1) * 7
  755.                         if no1wkst != firstwkst:
  756.                             i -= 7 - firstwkst
  757.                         
  758.                     else:
  759.                         i = no1wkst
  760.                     for j in range(7):
  761.                         self.wnomask[i] = 1
  762.                         i += 1
  763.                         if self.wdaymask[i] == rr._wkst:
  764.                             break
  765.                             continue
  766.                     
  767.                 
  768.                 if 1 in rr._byweekno:
  769.                     i = no1wkst + numweeks * 7
  770.                     if no1wkst != firstwkst:
  771.                         i -= 7 - firstwkst
  772.                     
  773.                     if i < self.yearlen:
  774.                         for j in range(7):
  775.                             self.wnomask[i] = 1
  776.                             i += 1
  777.                             if self.wdaymask[i] == rr._wkst:
  778.                                 break
  779.                                 continue
  780.                         
  781.                     
  782.                 
  783.                 if no1wkst:
  784.                     if -1 not in rr._byweekno:
  785.                         lyearweekday = datetime.date(year - 1, 1, 1).weekday()
  786.                         lno1wkst = ((7 - lyearweekday) + rr._wkst) % 7
  787.                         lyearlen = 365 + calendar.isleap(year - 1)
  788.                         if lno1wkst >= 4:
  789.                             lno1wkst = 0
  790.                             lnumweeks = 52 + ((lyearlen + (lyearweekday - rr._wkst) % 7) % 7) // 4
  791.                         else:
  792.                             lnumweeks = 52 + ((self.yearlen - no1wkst) % 7) // 4
  793.                     else:
  794.                         lnumweeks = -1
  795.                     if lnumweeks in rr._byweekno:
  796.                         for i in range(no1wkst):
  797.                             self.wnomask[i] = 1
  798.                         
  799.                     
  800.                 
  801.         
  802.         if rr._bynweekday:
  803.             if month != self.lastmonth or year != self.lastyear:
  804.                 ranges = []
  805.                 if rr._freq == YEARLY:
  806.                     if rr._bymonth:
  807.                         for month in rr._bymonth:
  808.                             ranges.append(self.mrange[month - 1:month + 1])
  809.                         
  810.                     else:
  811.                         ranges = [
  812.                             (0, self.yearlen)]
  813.                 elif rr._freq == MONTHLY:
  814.                     ranges = [
  815.                         self.mrange[month - 1:month + 1]]
  816.                 
  817.                 if ranges:
  818.                     self.nwdaymask = [
  819.                         0] * self.yearlen
  820.                     for first, last in ranges:
  821.                         last -= 1
  822.                         for wday, n in rr._bynweekday:
  823.                             if n < 0:
  824.                                 i = last + (n + 1) * 7
  825.                                 i -= (self.wdaymask[i] - wday) % 7
  826.                             else:
  827.                                 i = first + (n - 1) * 7
  828.                                 i += ((7 - self.wdaymask[i]) + wday) % 7
  829.                             if i <= i:
  830.                                 pass
  831.                             elif i <= last:
  832.                                 self.nwdaymask[i] = 1
  833.                                 continue
  834.                         
  835.                     
  836.                 
  837.             
  838.         if rr._byeaster:
  839.             self.eastermask = [
  840.                 0] * (self.yearlen + 7)
  841.             eyday = easter.easter(year).toordinal() - self.yearordinal
  842.             for offset in rr._byeaster:
  843.                 self.eastermask[eyday + offset] = 1
  844.             
  845.         
  846.         self.lastyear = year
  847.         self.lastmonth = month
  848.  
  849.     
  850.     def ydayset(self, year, month, day):
  851.         return (range(self.yearlen), 0, self.yearlen)
  852.  
  853.     
  854.     def mdayset(self, year, month, day):
  855.         set = [
  856.             None] * self.yearlen
  857.         (start, end) = self.mrange[month - 1:month + 1]
  858.         for i in range(start, end):
  859.             set[i] = i
  860.         
  861.         return (set, start, end)
  862.  
  863.     
  864.     def wdayset(self, year, month, day):
  865.         set = [
  866.             None] * (self.yearlen + 7)
  867.         i = datetime.date(year, month, day).toordinal() - self.yearordinal
  868.         start = i
  869.         for j in range(7):
  870.             set[i] = i
  871.             i += 1
  872.             if self.wdaymask[i] == self.rrule._wkst:
  873.                 break
  874.                 continue
  875.         
  876.         return (set, start, i)
  877.  
  878.     
  879.     def ddayset(self, year, month, day):
  880.         set = [
  881.             None] * self.yearlen
  882.         i = datetime.date(year, month, day).toordinal() - self.yearordinal
  883.         set[i] = i
  884.         return (set, i, i + 1)
  885.  
  886.     
  887.     def htimeset(self, hour, minute, second):
  888.         set = []
  889.         rr = self.rrule
  890.         for minute in rr._byminute:
  891.             for second in rr._bysecond:
  892.                 set.append(datetime.time(hour, minute, second, tzinfo = rr._tzinfo))
  893.             
  894.         
  895.         set.sort()
  896.         return set
  897.  
  898.     
  899.     def mtimeset(self, hour, minute, second):
  900.         set = []
  901.         rr = self.rrule
  902.         for second in rr._bysecond:
  903.             set.append(datetime.time(hour, minute, second, tzinfo = rr._tzinfo))
  904.         
  905.         set.sort()
  906.         return set
  907.  
  908.     
  909.     def stimeset(self, hour, minute, second):
  910.         return (datetime.time(hour, minute, second, tzinfo = self.rrule._tzinfo),)
  911.  
  912.  
  913.  
  914. class rruleset(rrulebase):
  915.     
  916.     class _genitem:
  917.         
  918.         def __init__(self, genlist, gen):
  919.             
  920.             try:
  921.                 self.dt = gen()
  922.                 genlist.append(self)
  923.             except StopIteration:
  924.                 pass
  925.  
  926.             self.genlist = genlist
  927.             self.gen = gen
  928.  
  929.         
  930.         def next(self):
  931.             
  932.             try:
  933.                 self.dt = self.gen()
  934.             except StopIteration:
  935.                 self.genlist.remove(self)
  936.  
  937.  
  938.         
  939.         def __cmp__(self, other):
  940.             return cmp(self.dt, other.dt)
  941.  
  942.  
  943.     
  944.     def __init__(self, cache = False):
  945.         rrulebase.__init__(self, cache)
  946.         self._rrule = []
  947.         self._rdate = []
  948.         self._exrule = []
  949.         self._exdate = []
  950.  
  951.     
  952.     def rrule(self, rrule):
  953.         self._rrule.append(rrule)
  954.  
  955.     
  956.     def rdate(self, rdate):
  957.         self._rdate.append(rdate)
  958.  
  959.     
  960.     def exrule(self, exrule):
  961.         self._exrule.append(exrule)
  962.  
  963.     
  964.     def exdate(self, exdate):
  965.         self._exdate.append(exdate)
  966.  
  967.     
  968.     def _iter(self):
  969.         rlist = []
  970.         self._rdate.sort()
  971.         self._genitem(rlist, iter(self._rdate).next)
  972.         for x in self._rrule:
  973.             pass
  974.         
  975.         rlist.sort()
  976.         exlist = []
  977.         self._exdate.sort()
  978.         self._genitem(exlist, iter(self._exdate).next)
  979.         for x in self._exrule:
  980.             pass
  981.         
  982.         exlist.sort()
  983.         lastdt = None
  984.         total = 0
  985.         while rlist:
  986.             ritem = rlist[0]
  987.             ritem.next()
  988.             rlist.sort()
  989.             continue
  990.             [] if not lastdt or lastdt != ritem.dt else _[1]
  991.         self._len = total
  992.  
  993.  
  994.  
  995. class _rrulestr:
  996.     _freq_map = {
  997.         'YEARLY': YEARLY,
  998.         'MONTHLY': MONTHLY,
  999.         'WEEKLY': WEEKLY,
  1000.         'DAILY': DAILY,
  1001.         'HOURLY': HOURLY,
  1002.         'MINUTELY': MINUTELY,
  1003.         'SECONDLY': SECONDLY }
  1004.     _weekday_map = {
  1005.         'MO': 0,
  1006.         'TU': 1,
  1007.         'WE': 2,
  1008.         'TH': 3,
  1009.         'FR': 4,
  1010.         'SA': 5,
  1011.         'SU': 6 }
  1012.     
  1013.     def _handle_int(self, rrkwargs, name, value, **kwargs):
  1014.         rrkwargs[name.lower()] = int(value)
  1015.  
  1016.     
  1017.     def _handle_int_list(self, rrkwargs, name, value, **kwargs):
  1018.         rrkwargs[name.lower()] = [ int(x) for x in value.split(',') ]
  1019.  
  1020.     _handle_INTERVAL = _handle_int
  1021.     _handle_COUNT = _handle_int
  1022.     _handle_BYSETPOS = _handle_int_list
  1023.     _handle_BYMONTH = _handle_int_list
  1024.     _handle_BYMONTHDAY = _handle_int_list
  1025.     _handle_BYYEARDAY = _handle_int_list
  1026.     _handle_BYEASTER = _handle_int_list
  1027.     _handle_BYWEEKNO = _handle_int_list
  1028.     _handle_BYHOUR = _handle_int_list
  1029.     _handle_BYMINUTE = _handle_int_list
  1030.     _handle_BYSECOND = _handle_int_list
  1031.     
  1032.     def _handle_FREQ(self, rrkwargs, name, value, **kwargs):
  1033.         rrkwargs['freq'] = self._freq_map[value]
  1034.  
  1035.     
  1036.     def _handle_UNTIL(self, rrkwargs, name, value, **kwargs):
  1037.         global parser
  1038.         if not parser:
  1039.             parser = parser
  1040.             import dateutil
  1041.         
  1042.         
  1043.         try:
  1044.             rrkwargs['until'] = parser.parse(value, ignoretz = kwargs.get('ignoretz'), tzinfos = kwargs.get('tzinfos'))
  1045.         except ValueError:
  1046.             raise ValueError, 'invalid until date'
  1047.  
  1048.  
  1049.     
  1050.     def _handle_WKST(self, rrkwargs, name, value, **kwargs):
  1051.         rrkwargs['wkst'] = self._weekday_map[value]
  1052.  
  1053.     
  1054.     def _handle_BYWEEKDAY(self, rrkwargs, name, value, **kwarsg):
  1055.         l = []
  1056.         for wday in value.split(','):
  1057.             for i in range(len(wday)):
  1058.                 if wday[i] not in '+-0123456789':
  1059.                     break
  1060.                     continue
  1061.             
  1062.             if not wday[:i]:
  1063.                 pass
  1064.             n = None
  1065.             w = wday[i:]
  1066.             if n:
  1067.                 n = int(n)
  1068.             
  1069.             l.append(weekdays[self._weekday_map[w]](n))
  1070.         
  1071.         rrkwargs['byweekday'] = l
  1072.  
  1073.     _handle_BYDAY = _handle_BYWEEKDAY
  1074.     
  1075.     def _parse_rfc_rrule(self, line, dtstart = None, cache = False, ignoretz = False, tzinfos = None):
  1076.         if line.find(':') != -1:
  1077.             (name, value) = line.split(':')
  1078.             if name != 'RRULE':
  1079.                 raise ValueError, 'unknown parameter name'
  1080.             name != 'RRULE'
  1081.         else:
  1082.             value = line
  1083.         rrkwargs = { }
  1084.         for pair in value.split(';'):
  1085.             (name, value) = pair.split('=')
  1086.             name = name.upper()
  1087.             value = value.upper()
  1088.             
  1089.             try:
  1090.                 getattr(self, '_handle_' + name)(rrkwargs, name, value, ignoretz = ignoretz, tzinfos = tzinfos)
  1091.             continue
  1092.             except AttributeError:
  1093.                 raise ValueError, "unknown parameter '%s'" % name
  1094.                 continue
  1095.                 except (KeyError, ValueError):
  1096.                     raise ValueError, "invalid '%s': %s" % (name, value)
  1097.                     continue
  1098.                 
  1099.             return rrule(dtstart = dtstart, cache = cache, **rrkwargs)
  1100.  
  1101.  
  1102.     
  1103.     def _parse_rfc(self, s, dtstart = None, cache = False, unfold = False, forceset = False, compatible = False, ignoretz = False, tzinfos = None):
  1104.         global parser, parser
  1105.         if compatible:
  1106.             forceset = True
  1107.             unfold = True
  1108.         
  1109.         s = s.upper()
  1110.         if not s.strip():
  1111.             raise ValueError, 'empty string'
  1112.         s.strip()
  1113.         if unfold:
  1114.             lines = s.splitlines()
  1115.             i = 0
  1116.             while i < len(lines):
  1117.                 line = lines[i].rstrip()
  1118.                 if not line:
  1119.                     del lines[i]
  1120.                     continue
  1121.                 if i > 0 and line[0] == ' ':
  1122.                     lines[i - 1] += line[1:]
  1123.                     del lines[i]
  1124.                     continue
  1125.                 i += 1
  1126.         else:
  1127.             lines = s.split()
  1128.         if not forceset and len(lines) == 1:
  1129.             if s.find(':') == -1 or s.startswith('RRULE:'):
  1130.                 return self._parse_rfc_rrule(lines[0], cache = cache, dtstart = dtstart, ignoretz = ignoretz, tzinfos = tzinfos)
  1131.             rrulevals = []
  1132.             rdatevals = []
  1133.             exrulevals = []
  1134.             exdatevals = []
  1135.             for line in lines:
  1136.                 if not line:
  1137.                     continue
  1138.                 
  1139.                 if line.find(':') == -1:
  1140.                     name = 'RRULE'
  1141.                     value = line
  1142.                 else:
  1143.                     (name, value) = line.split(':', 1)
  1144.                 parms = name.split(';')
  1145.                 if not parms:
  1146.                     raise ValueError, 'empty property name'
  1147.                 parms
  1148.                 name = parms[0]
  1149.                 parms = parms[1:]
  1150.                 if name == 'RRULE':
  1151.                     for parm in parms:
  1152.                         raise ValueError, 'unsupported RRULE parm: ' + parm
  1153.                     
  1154.                     rrulevals.append(value)
  1155.                     continue
  1156.                 if name == 'RDATE':
  1157.                     for parm in parms:
  1158.                         if parm != 'VALUE=DATE-TIME':
  1159.                             raise ValueError, 'unsupported RDATE parm: ' + parm
  1160.                         parm != 'VALUE=DATE-TIME'
  1161.                     
  1162.                     rdatevals.append(value)
  1163.                     continue
  1164.                 if name == 'EXRULE':
  1165.                     for parm in parms:
  1166.                         raise ValueError, 'unsupported EXRULE parm: ' + parm
  1167.                     
  1168.                     exrulevals.append(value)
  1169.                     continue
  1170.                 if name == 'EXDATE':
  1171.                     for parm in parms:
  1172.                         if parm != 'VALUE=DATE-TIME':
  1173.                             raise ValueError, 'unsupported RDATE parm: ' + parm
  1174.                         parm != 'VALUE=DATE-TIME'
  1175.                     
  1176.                     exdatevals.append(value)
  1177.                     continue
  1178.                 if name == 'DTSTART':
  1179.                     for parm in parms:
  1180.                         raise ValueError, 'unsupported DTSTART parm: ' + parm
  1181.                     
  1182.                     if not parser:
  1183.                         parser = parser
  1184.                         import dateutil
  1185.                     
  1186.                     dtstart = parser.parse(value, ignoretz = ignoretz, tzinfos = tzinfos)
  1187.                     continue
  1188.                 raise ValueError, 'unsupported property: ' + name
  1189.             
  1190.         if forceset and len(rrulevals) > 1 and rdatevals and exrulevals or exdatevals:
  1191.             if not parser:
  1192.                 if rdatevals or exdatevals:
  1193.                     parser = parser
  1194.                     import dateutil
  1195.                 
  1196.             set = rruleset(cache = cache)
  1197.             for value in rrulevals:
  1198.                 set.rrule(self._parse_rfc_rrule(value, dtstart = dtstart, ignoretz = ignoretz, tzinfos = tzinfos))
  1199.             
  1200.             for value in rdatevals:
  1201.                 for datestr in value.split(','):
  1202.                     set.rdate(parser.parse(datestr, ignoretz = ignoretz, tzinfos = tzinfos))
  1203.                 
  1204.             
  1205.             for value in exrulevals:
  1206.                 set.exrule(self._parse_rfc_rrule(value, dtstart = dtstart, ignoretz = ignoretz, tzinfos = tzinfos))
  1207.             
  1208.             for value in exdatevals:
  1209.                 for datestr in value.split(','):
  1210.                     set.exdate(parser.parse(datestr, ignoretz = ignoretz, tzinfos = tzinfos))
  1211.                 
  1212.             
  1213.             if compatible and dtstart:
  1214.                 set.rdate(dtstart)
  1215.             
  1216.             return set
  1217.         return self._parse_rfc_rrule(rrulevals[0], dtstart = dtstart, cache = cache, ignoretz = ignoretz, tzinfos = tzinfos)
  1218.  
  1219.     
  1220.     def __call__(self, s, **kwargs):
  1221.         return self._parse_rfc(s, **kwargs)
  1222.  
  1223.  
  1224. rrulestr = _rrulestr()
  1225.