class SameNthWeekdayFromBeginningInMonthBase(SameNthWeekdayInMonthBase): """Base class For recurrings on the same day nth weekday in month counting from the beginning of the month. """ grok.baseclass() n_mapping = { 0: _('1st'), 1: _('2nd'), 2: _('3rd'), 3: _('4th'), 4: _('5th') } @zope.cachedescriptors.property.Lazy def n(self): return int(math.ceil(self.context.day / 7.0)) - 1 @property def info(self): return _(self.message_id, mapping={ 'recurrence': self.n_mapping[self.n], 'weekday': self._weekday })
class SameNthWeekdayFromEndInMonthBase(SameNthWeekdayInMonthBase): """Base class for recurrings on the same day nth weekday in month ... ... counting from the end of the month. """ grok.baseclass() n_mapping = { 1: _('last'), 2: _('last but one'), 3: _('last but two'), 4: _('last but three'), 5: _('last but four') } @zope.cachedescriptors.property.Lazy def n_from_end(self): last_of_month = gocept.month.IMonth(self.context).lastOfMonth() return int( math.ceil((last_of_month.day - (self.context.day - 1)) / 7.0)) @property def n(self): return recurrences_of_weekday_in_month( self.context, self.current_month) - self.n_from_end @property def info(self): return _(self.message_id, mapping={ 'recurrence': self.n_mapping[self.n_from_end], 'weekday': self._weekday })
class MonthlyNthWeekday(SameNthWeekdayFromBeginningInMonthBase): """Recurring monthly on same recurrence of the weekday in the month as ... ... in `self.context`. """ grok.name('nth weekday of month') weight = 20 title = _('monthly, same weekday (e. g. each 3rd Sunday)') month_interval = 1 message_id = _('${recurrence} ${weekday} every month')
class Daily(StaticIntervalBase): """Recurring each day.""" grok.name('daily') weight = 5 interval = ONE_DAY title = _('daily') info = _('each day') def _get_start_date(self): return self.interval_start
class BiMonthlyNthWeekday(SameNthWeekdayFromBeginningInMonthBase): """Recurring monthly on same recurrence of the weekday in the month as ... ... in `self.context` but only every other month. """ grok.name('nth weekday every other month') weight = 25 title = _('every other month, same weekday ' '(e. g. each 3rd Sunday in other month)') month_interval = 2 message_id = _('${recurrence} ${weekday} every other month')
class BiMonthlyNthWeekdayFromEnd(SameNthWeekdayFromEndInMonthBase): """Recurring monthly on same recurrence of the weekday in the month as ... ... in `self.context` but only each other month. """ grok.name('nth weekday from end of other month') weight = 26 title = _('every other month on same weekday counted from the end of the ' 'month (e. g. each last but one Sunday every other month)') month_interval = 2 message_id = _('${recurrence} ${weekday} every other month')
class MonthlyNthWeekdayFromEnd(SameNthWeekdayFromEndInMonthBase): """Recurring monthly on same recurrence of the weekday in the month as ... ... in `self.context`. """ grok.name('nth weekday from end of month') weight = 21 title = _('monthly, same weekday counted from the end of the month ' '(e. g. each last but one Sunday)') month_interval = 1 message_id = _('${recurrence} ${weekday} every month')
class BiWeekly(SameWeekdayBase): """Recurring biweekly on the same weekday.""" grok.name('biweekly') weight = 11 title = _('every other week, same weekday (e. g. each second Friday)') interval = TWO_WEEKS def _get_start_date(self): candiate = next_date_of_same_weekday(self.context, self.interval_start) # We have to compare the naive datetimes as otherwise the DST # difference might be computed into the difference of the two dates: naive_candiate = self.combine_with_time_of_context( candiate).replace(tzinfo=None) naive_context = self.context.replace(tzinfo=None) interval = (naive_candiate - naive_context).days assert interval % 7 == 0, \ 'Interval has {} days. This is {} weeks and {} days!'.format( interval, interval / 7, interval % 7) if interval % 14 != 0: # odd number of weeks candiate = next_date_of_same_weekday( self.context, self.interval_start + ONE_WEEK) return candiate @property def info(self): return _('${weekday} every other week', mapping={'weekday': self._weekday})
class Yearly(RecurringDateTime): """Recurring on the same date each year.""" grok.name('yearly') weight = 100 title = _('yearly (e. g. 24th of December)') def compute(self): if self.context > self.interval_end: return # no need to compute: there will be no results date = self.context index = 0 # Find first date after interval_start: while date < self.interval_start: index += 1 date = add_years(self.context, index) # Yield dates in the interval: while date < self.interval_end: yield date index += 1 date = add_years(self.context, index) @property def info(self): return _('${date} every year', mapping={'date': self.context.strftime('%d.%m.')})
class Weekly(SameWeekdayBase): """Recurring weekly on the same weekday.""" grok.name('weekly') weight = 10 title = _('weekly, same weekday (e. g. each Friday)') interval = ONE_WEEK @property def info(self): return _('${weekday} every week', mapping={'weekday': self._weekday})
def info(self): return _(self.message_id, mapping={ 'recurrence': self.n_mapping[self.n], 'weekday': self._weekday })
def info(self): return _('${weekday} every other week', mapping={'weekday': self._weekday})
def info(self): return _('${date} every year', mapping={'date': self.context.strftime('%d.%m.')})