<s> from __future__ import unicode_literals <EOL> from collections import defaultdict <EOL> from datetime import date , timedelta <EOL> from django . utils . six . moves import xrange <EOL> class Repeater ( object ) : <EOL> def __init__ ( self , count , year , month , day = None , end_repeat = None , <EOL> event = None , num = <NUM_LIT:7> , count_first = False , end_on = None ) : <EOL> self . count = count <EOL> self . year = year <EOL> self . month = month <EOL> self . day = day <EOL> self . end_repeat = end_repeat <EOL> self . event = event <EOL> self . num = num <EOL> self . count_first = count_first <EOL> self . end_on = end_on <EOL> if end_repeat is None : <EOL> self . end_repeat = date ( <NUM_LIT> , <NUM_LIT:3> , <NUM_LIT:3> ) <EOL> def count_it ( self , day ) : <EOL> self . count [ day ] . append ( ( self . event . title , self . event . pk ) ) <EOL> def repeat ( self , day = None ) : <EOL> """<STR_LIT>""" <EOL> if day is None : <EOL> day = self . day <EOL> try : <EOL> d = date ( self . year , self . month , day ) <EOL> except ValueError : <EOL> return self . count <EOL> if self . count_first and d <= self . end_repeat : <EOL> self . count_it ( d . day ) <EOL> d += timedelta ( days = self . num ) <EOL> if self . end_on is not None : <EOL> while d . month == self . month and d <= self . end_repeat and d . day <= self . end_on : <EOL> self . count_it ( d . day ) <EOL> d += timedelta ( days = self . num ) <EOL> else : <EOL> while d . month == self . month and d <= self . end_repeat : <EOL> self . count_it ( d . day ) <EOL> d += timedelta ( days = self . num ) <EOL> def repeat_weekdays ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> d = date ( self . year , self . month , self . day ) <EOL> except ValueError : <EOL> return self . count <EOL> if self . count_first and d <= self . end_repeat and d . weekday ( ) not in ( <NUM_LIT:5> , <NUM_LIT:6> ) : <EOL> self . count_it ( d . day ) <EOL> d += timedelta ( days = <NUM_LIT:1> ) <EOL> while d . month == self . month and d <= self . end_repeat : <EOL> if d . weekday ( ) not in ( <NUM_LIT:5> , <NUM_LIT:6> ) : <EOL> self . count_it ( d . day ) <EOL> d += timedelta ( days = <NUM_LIT:1> ) <EOL> def repeat_reverse ( self , start , end ) : <EOL> """<STR_LIT>""" <EOL> day = start <EOL> diff = start - end <EOL> try : <EOL> if date ( self . year , self . month , day ) <= self . end_repeat : <EOL> self . count_it ( day ) <EOL> except ValueError : <EOL> pass <EOL> for i in xrange ( diff ) : <EOL> day -= <NUM_LIT:1> <EOL> try : <EOL> if date ( self . year , self . month , day ) <= self . end_repeat : <EOL> self . count_it ( day ) <EOL> except ValueError : <EOL> pass <EOL> def repeat_chunk ( self , diff ) : <EOL> for i in xrange ( diff ) : <EOL> self . repeat ( self . day + i + <NUM_LIT:1> ) <EOL> def repeat_biweekly ( self ) : <EOL> """<STR_LIT>""" <EOL> mycount = defaultdict ( list ) <EOL> d = self . event . l_start_date <EOL> while d . year != self . year or d . month != self . month : <EOL> d += timedelta ( days = <NUM_LIT> ) <EOL> r = self . __class__ ( <EOL> mycount , self . year , self . month , d . day , self . event . end_repeat , <EOL> self . event , num = self . num , count_first = True <EOL> ) <EOL> r . repeat ( ) <EOL> if self . event . is_chunk ( ) and r . count : <EOL> r . day = min ( r . count ) <EOL> r . repeat_chunk ( self . event . start_end_diff ) <EOL> return r . count <EOL> class YearlyRepeater ( Repeater ) : <EOL> def _repeat_chunk ( self ) : <EOL> self . day = self . event . l_start_date . day <EOL> self . num = <NUM_LIT:1> <EOL> if self . event . end_repeat is not None : <EOL> self . end_repeat = self . event . end_repeat <EOL> if self . event . l_start_date . month == self . month : <EOL> if self . event . starts_ends_same_month ( ) : <EOL> self . end_on = self . event . l_end_date . day <EOL> self . repeat ( ) <EOL> elif ( self . event . l_end_date . month == self . month <EOL> and not self . event . starts_ends_same_month ( ) ) : <EOL> self . repeat_reverse ( self . event . l_end_date . day , <NUM_LIT:1> ) <EOL> def repeat_it ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . event . l_start_date . month == self . month and self . event . l_start_date . year != self . year : <EOL> self . count_it ( self . event . l_start_date . day ) <EOL> if self . event . is_chunk ( ) and not self . event . starts_same_year_month_as ( self . year , self . month ) : <EOL> self . _repeat_chunk ( ) <EOL> return self . count <EOL> class MonthlyRepeater ( Repeater ) : <EOL> def _repeat_chunk ( self ) : <EOL> start_day = self . event . l_start_date . day <EOL> last_day_last_mo = date ( self . year , self . month , <NUM_LIT:1> ) - timedelta ( days = <NUM_LIT:1> ) <EOL> self . day = start_day <EOL> self . num = <NUM_LIT:1> <EOL> if self . event . end_repeat is not None : <EOL> self . end_repeat = self . event . end_repeat <EOL> if not self . event . starts_same_year_month_as ( self . year , self . month ) : <EOL> if not self . event . starts_ends_same_month ( ) : <EOL> self . repeat ( ) <EOL> if start_day <= last_day_last_mo . day : <EOL> self . repeat_reverse ( <EOL> self . event . l_end_date . day , <NUM_LIT:1> <EOL> ) <EOL> else : <EOL> self . repeat_reverse ( <EOL> self . event . l_end_date . day , start_day + <NUM_LIT:1> <EOL> ) <EOL> def repeat_it ( self ) : <EOL> """<STR_LIT>""" <EOL> start_day = self . event . l_start_date . day <EOL> if not self . event . starts_same_month_as ( self . month ) : <EOL> self . count_it ( start_day ) <EOL> elif self . event . starts_same_month_not_year_as ( self . month , self . year ) : <EOL> self . count_it ( start_day ) <EOL> if self . event . is_chunk ( ) : <EOL> self . _repeat_chunk ( ) <EOL> return self . count <EOL> class DailyRepeater ( Repeater ) : <EOL> """<STR_LIT>""" <EOL> def repeat_it ( self ) : <EOL> if self . event . end_repeat is not None : <EOL> self . end_repeat = self . event . end_repeat <EOL> if self . event . starts_same_year_month_as ( self . year , self . month ) : <EOL> self . day = self . event . l_start_date . day <EOL> else : <EOL> self . day = date ( self . year , self . month , <NUM_LIT:1> ) . day <EOL> self . count_first = True <EOL> if self . event . repeats ( '<STR_LIT>' ) : <EOL> self . num = <NUM_LIT:1> <EOL> self . repeat ( ) <EOL> else : <EOL> self . repeat_weekdays ( ) <EOL> return self . count <EOL> class WeeklyRepeater ( Repeater ) : <EOL> def _biweekly_helper ( self ) : <EOL> """<STR_LIT>""" <EOL> self . num = <NUM_LIT> <EOL> mycount = self . repeat_biweekly ( ) <EOL> if mycount : <EOL> if self . event . is_chunk ( ) and min ( mycount ) not in xrange ( <NUM_LIT:1> , <NUM_LIT:8> ) : <EOL> mycount = _chunk_fill_out_first_week ( <EOL> self . year , self . month , mycount , self . event , <EOL> diff = self . event . start_end_diff , <EOL> ) <EOL> for k , v in mycount . items ( ) : <EOL> for item in v : <EOL> self . count [ k ] . append ( item ) <EOL> def _handle_weekly_repeat_out ( self ) : <EOL> """<STR_LIT>""" <EOL> start_d = _first_weekday ( <EOL> self . event . l_start_date . weekday ( ) , date ( self . year , self . month , <NUM_LIT:1> ) <EOL> ) <EOL> self . day = start_d . day <EOL> self . count_first = True <EOL> if self . event . repeats ( '<STR_LIT>' ) : <EOL> self . _biweekly_helper ( ) <EOL> elif self . event . repeats ( '<STR_LIT>' ) : <EOL> self . repeat ( ) <EOL> if self . event . is_chunk ( ) : <EOL> diff = self . event . start_end_diff <EOL> self . count = _chunk_fill_out_first_week ( <EOL> self . year , self . month , self . count , self . event , diff <EOL> ) <EOL> for i in xrange ( diff ) : <EOL> self . day = start_d . day + i + <NUM_LIT:1> <EOL> self . repeat ( ) <EOL> def _handle_weekly_repeat_in ( self ) : <EOL> """<STR_LIT>""" <EOL> self . day = self . event . l_start_date . day <EOL> self . count_first = False <EOL> repeats = { '<STR_LIT>' : <NUM_LIT:7> , '<STR_LIT>' : <NUM_LIT> } <EOL> if self . event . starts_same_year_month_as ( self . year , self . month ) : <EOL> for repeat , num in repeats . items ( ) : <EOL> self . num = num <EOL> if self . event . repeats ( repeat ) : <EOL> self . repeat ( ) <EOL> if self . event . is_chunk ( ) : <EOL> self . repeat_chunk ( diff = self . event . start_end_diff ) <EOL> def repeat_it ( self ) : <EOL> if self . event . end_repeat is not None : <EOL> self . end_repeat = self . event . end_repeat <EOL> if self . event . starts_same_year_month_as ( self . year , self . month ) : <EOL> self . _handle_weekly_repeat_in ( ) <EOL> else : <EOL> self . _handle_weekly_repeat_out ( ) <EOL> return self . count <EOL> def _first_weekday ( weekday , d ) : <EOL> """<STR_LIT>""" <EOL> while weekday != d . weekday ( ) : <EOL> d += timedelta ( days = <NUM_LIT:1> ) <EOL> return d <EOL> def _chunk_fill_out_first_week ( year , month , count , event , diff ) : <EOL> """<STR_LIT>""" <EOL> first_of_the_month = date ( year , month , <NUM_LIT:1> ) <EOL> d = _first_weekday ( event . l_end_date . weekday ( ) , first_of_the_month ) <EOL> d2 = _first_weekday ( event . l_start_date . weekday ( ) , first_of_the_month ) <EOL> diff_weekdays = d . day - d2 . day <EOL> day = first_of_the_month . day <EOL> start = event . l_start_date . weekday ( ) <EOL> first = first_of_the_month . weekday ( ) <EOL> if start == first or diff_weekdays == diff : <EOL> return count <EOL> elif start > first : <EOL> end = event . l_end_date . weekday ( ) <EOL> diff = end - first + <NUM_LIT:1> <EOL> elif start < first : <EOL> diff = d . day <EOL> for i in xrange ( diff ) : <EOL> if event . end_repeat is not None and date ( year , month , day ) >= event . end_repeat : <EOL> break <EOL> count [ day ] . append ( ( event . title , event . pk ) ) <EOL> day += <NUM_LIT:1> <EOL> return count <EOL> class CountHandler ( object ) : <EOL> def __init__ ( self , year , month , events ) : <EOL> self . year = year <EOL> self . month = month <EOL> self . events = events <EOL> self . count = defaultdict ( list ) <EOL> def _handle_single_chunk ( self , event ) : <EOL> """<STR_LIT>""" <EOL> if not event . starts_same_month_as ( self . month ) and not event . repeats ( '<STR_LIT>' ) : <EOL> return <EOL> mycount = defaultdict ( list ) <EOL> r = Repeater ( <EOL> mycount , self . year , self . month , day = event . l_start_date . day , <EOL> end_repeat = event . end_repeat , event = event , count_first = True , <EOL> end_on = event . l_end_date . day , num = <NUM_LIT:1> <EOL> ) <EOL> if event . starts_same_month_as ( self . month ) : <EOL> if not event . ends_same_month_as ( self . month ) : <EOL> r . end_on = None <EOL> else : <EOL> r . day = <NUM_LIT:1> <EOL> r . repeat ( ) <EOL> for k , v in r . count . items ( ) : <EOL> self . count [ k ] . extend ( v ) <EOL> def _handle_month_event ( self , event ) : <EOL> if event . is_chunk ( ) : <EOL> self . _handle_single_chunk ( event ) <EOL> elif event . repeats ( '<STR_LIT>' ) : <EOL> if event . l_start_date . weekday ( ) not in ( <NUM_LIT:5> , <NUM_LIT:6> ) : <EOL> self . count [ event . l_start_date . day ] . append ( <EOL> ( event . title , event . pk ) <EOL> ) <EOL> else : <EOL> self . count [ event . l_start_date . day ] . append ( ( event . title , event . pk ) ) <EOL> def get_count ( self ) : <EOL> kwargs = { '<STR_LIT>' : self . year , '<STR_LIT>' : self . month , '<STR_LIT:count>' : self . count } <EOL> for event in self . events : <EOL> kwargs [ '<STR_LIT>' ] = event <EOL> if event . starts_ends_yr_mo ( self . year , self . month ) : <EOL> self . _handle_month_event ( event ) <EOL> if event . repeats ( '<STR_LIT>' ) or event . repeats ( '<STR_LIT>' ) : <EOL> r = WeeklyRepeater ( ** kwargs ) <EOL> elif event . repeats ( '<STR_LIT>' ) : <EOL> r = MonthlyRepeater ( ** kwargs ) <EOL> elif event . repeats ( '<STR_LIT>' ) or event . repeats ( '<STR_LIT>' ) : <EOL> r = DailyRepeater ( ** kwargs ) <EOL> else : <EOL> r = YearlyRepeater ( ** kwargs ) <EOL> self . count = r . repeat_it ( ) <EOL> return self . count </s>
