<s> import datetime <EOL> from dateutil . rrule import rrule , YEARLY , MONTHLY , WEEKLY , DAILY <EOL> from operator import itemgetter <EOL> from django . conf import settings <EOL> from django . core . urlresolvers import reverse <EOL> from django . db import models <EOL> from django . db . models import Q <EOL> from django . template . defaultfilters import date <EOL> from django . utils import timezone <EOL> from django . utils . functional import cached_property <EOL> from django . utils . translation import ugettext_lazy as _ <EOL> from cms . models import ContentManageable , NameSlugModel <EOL> from markupfield . fields import MarkupField <EOL> from timedelta . fields import TimedeltaField <EOL> from timedelta . helpers import nice_repr as timedelta_nice_repr <EOL> from timedelta . helpers import parse as timedelta_parse <EOL> from . utils import minutes_resolution <EOL> DEFAULT_MARKUP_TYPE = getattr ( settings , '<STR_LIT>' , '<STR_LIT>' ) <EOL> class Calendar ( ContentManageable ) : <EOL> url = models . URLField ( '<STR_LIT>' , blank = True , null = True ) <EOL> rss = models . URLField ( '<STR_LIT>' , blank = True , null = True ) <EOL> embed = models . URLField ( '<STR_LIT>' , blank = True , null = True ) <EOL> twitter = models . URLField ( '<STR_LIT>' , blank = True , null = True ) <EOL> name = models . CharField ( max_length = <NUM_LIT:100> ) <EOL> slug = models . SlugField ( unique = True ) <EOL> description = models . CharField ( max_length = <NUM_LIT:255> , null = True , blank = True ) <EOL> def __str__ ( self ) : <EOL> return self . name <EOL> def get_absolute_url ( self ) : <EOL> return reverse ( '<STR_LIT>' , kwargs = { '<STR_LIT>' : self . slug } ) <EOL> def import_events ( self ) : <EOL> if self . url is None : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> from . importer import ICSImporter <EOL> importer = ICSImporter ( calendar = self ) <EOL> importer . import_events ( ) <EOL> class EventCategory ( NameSlugModel ) : <EOL> calendar = models . ForeignKey ( Calendar , related_name = '<STR_LIT>' , null = True , blank = True ) <EOL> class Meta : <EOL> verbose_name_plural = '<STR_LIT>' <EOL> ordering = ( '<STR_LIT:name>' , ) <EOL> def get_absolute_url ( self ) : <EOL> return reverse ( '<STR_LIT>' , kwargs = { '<STR_LIT>' : self . calendar . slug , '<STR_LIT>' : self . slug } ) <EOL> class EventLocation ( models . Model ) : <EOL> calendar = models . ForeignKey ( Calendar , related_name = '<STR_LIT>' , null = True , blank = True ) <EOL> name = models . CharField ( max_length = <NUM_LIT:255> ) <EOL> address = models . CharField ( blank = True , null = True , max_length = <NUM_LIT:255> ) <EOL> url = models . URLField ( '<STR_LIT>' , blank = True , null = True ) <EOL> class Meta : <EOL> ordering = ( '<STR_LIT:name>' , ) <EOL> def __str__ ( self ) : <EOL> return self . name <EOL> def get_absolute_url ( self ) : <EOL> return reverse ( '<STR_LIT>' , kwargs = { '<STR_LIT>' : self . calendar . slug , '<STR_LIT>' : self . pk } ) <EOL> class EventManager ( models . Manager ) : <EOL> def for_datetime ( self , dt = None ) : <EOL> if dt is None : <EOL> dt = timezone . now ( ) <EOL> return self . filter ( Q ( occurring_rule__dt_start__gt = dt ) | Q ( recurring_rules__finish__gt = dt ) ) <EOL> def until_datetime ( self , dt = None ) : <EOL> if dt is None : <EOL> dt = timezone . now ( ) <EOL> return self . filter ( Q ( occurring_rule__dt_end__lt = dt ) | Q ( recurring_rules__begin__lt = dt ) ) <EOL> class Event ( ContentManageable ) : <EOL> uid = models . CharField ( max_length = <NUM_LIT:200> , null = True , blank = True ) <EOL> title = models . CharField ( max_length = <NUM_LIT:200> ) <EOL> calendar = models . ForeignKey ( Calendar , related_name = '<STR_LIT>' ) <EOL> description = MarkupField ( default_markup_type = DEFAULT_MARKUP_TYPE , escape_html = False ) <EOL> venue = models . ForeignKey ( EventLocation , null = True , blank = True , related_name = '<STR_LIT>' ) <EOL> categories = models . ManyToManyField ( EventCategory , related_name = '<STR_LIT>' , blank = True , null = True ) <EOL> featured = models . BooleanField ( default = False , db_index = True ) <EOL> objects = EventManager ( ) <EOL> class Meta : <EOL> ordering = ( '<STR_LIT>' , ) <EOL> def __str__ ( self ) : <EOL> return self . title <EOL> def get_absolute_url ( self ) : <EOL> return reverse ( '<STR_LIT>' , kwargs = { '<STR_LIT>' : self . calendar . slug , '<STR_LIT>' : self . pk } ) <EOL> @ cached_property <EOL> def previous_event ( self ) : <EOL> dt = self . next_time . dt_end <EOL> try : <EOL> return Event . objects . until_datetime ( dt ) . filter ( calendar = self . calendar ) [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> return None <EOL> @ cached_property <EOL> def next_event ( self ) : <EOL> dt = self . next_time . dt_start <EOL> try : <EOL> return Event . objects . for_datetime ( dt ) . filter ( calendar = self . calendar ) [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> return None <EOL> @ property <EOL> def next_time ( self ) : <EOL> """<STR_LIT>""" <EOL> now = timezone . now ( ) <EOL> recurring_start = occurring_start = None <EOL> try : <EOL> occurring_rule = self . occurring_rule <EOL> except OccurringRule . DoesNotExist : <EOL> pass <EOL> else : <EOL> if occurring_rule and occurring_rule . dt_start > now : <EOL> occurring_start = ( occurring_rule . dt_start , occurring_rule ) <EOL> rrules = self . recurring_rules . filter ( finish__gt = now ) <EOL> recurring_starts = [ ( rule . dt_start , rule ) for rule in rrules if rule . dt_start is not None ] <EOL> recurring_starts . sort ( key = itemgetter ( <NUM_LIT:0> ) ) <EOL> try : <EOL> recurring_start = recurring_starts [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> pass <EOL> starts = [ i for i in ( recurring_start , occurring_start ) if i is not None ] <EOL> starts . sort ( key = itemgetter ( <NUM_LIT:0> ) ) <EOL> try : <EOL> return starts [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> except IndexError : <EOL> return None <EOL> @ property <EOL> def previous_time ( self ) : <EOL> now = timezone . now ( ) <EOL> recurring_end = occurring_end = None <EOL> try : <EOL> occurring_rule = self . occurring_rule <EOL> except OccurringRule . DoesNotExist : <EOL> pass <EOL> else : <EOL> if occurring_rule and occurring_rule . dt_end < now : <EOL> occurring_end = ( occurring_rule . dt_end , occurring_rule ) <EOL> rrules = self . recurring_rules . filter ( begin__lt = now ) <EOL> recurring_ends = [ ( rule . dt_end , rule ) for rule in rrules if rule . dt_end is not None ] <EOL> recurring_ends . sort ( key = itemgetter ( <NUM_LIT:0> ) , reverse = True ) <EOL> try : <EOL> recurring_end = recurring_ends [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> pass <EOL> ends = [ i for i in ( recurring_end , occurring_end ) if i is not None ] <EOL> ends . sort ( key = itemgetter ( <NUM_LIT:0> ) , reverse = True ) <EOL> try : <EOL> return ends [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> except IndexError : <EOL> return None <EOL> @ property <EOL> def next_or_previous_time ( self ) : <EOL> return self . next_time or self . previous_time <EOL> @ property <EOL> def is_past ( self ) : <EOL> return self . next_time is None <EOL> class RuleMixin : <EOL> def valid_dt_end ( self ) : <EOL> return minutes_resolution ( self . dt_end ) > minutes_resolution ( self . dt_start ) <EOL> class OccurringRule ( RuleMixin , models . Model ) : <EOL> """<STR_LIT>""" <EOL> event = models . OneToOneField ( Event , related_name = '<STR_LIT>' ) <EOL> dt_start = models . DateTimeField ( default = timezone . now ) <EOL> dt_end = models . DateTimeField ( default = timezone . now ) <EOL> all_day = models . BooleanField ( default = False ) <EOL> def __str__ ( self ) : <EOL> strftime = settings . SHORT_DATETIME_FORMAT <EOL> return '<STR_LIT>' % ( self . event . title , date ( self . dt_start . strftime , strftime ) , date ( self . dt_end . strftime , strftime ) ) <EOL> @ property <EOL> def begin ( self ) : <EOL> return self . dt_start <EOL> @ property <EOL> def finish ( self ) : <EOL> return self . dt_end <EOL> @ property <EOL> def duration ( self ) : <EOL> return self . dt_end - self . dt_start <EOL> @ property <EOL> def single_day ( self ) : <EOL> return self . dt_start . date ( ) == self . dt_end . date ( ) <EOL> class RecurringRule ( RuleMixin , models . Model ) : <EOL> """<STR_LIT>""" <EOL> FREQ_CHOICES = ( <EOL> ( YEARLY , '<STR_LIT>' ) , <EOL> ( MONTHLY , '<STR_LIT>' ) , <EOL> ( WEEKLY , '<STR_LIT>' ) , <EOL> ( DAILY , '<STR_LIT>' ) , <EOL> ) <EOL> event = models . ForeignKey ( Event , related_name = '<STR_LIT>' ) <EOL> begin = models . DateTimeField ( default = timezone . now ) <EOL> finish = models . DateTimeField ( default = timezone . now ) <EOL> duration = TimedeltaField ( default = '<STR_LIT>' ) <EOL> interval = models . PositiveSmallIntegerField ( default = <NUM_LIT:1> ) <EOL> frequency = models . PositiveSmallIntegerField ( FREQ_CHOICES , default = WEEKLY ) <EOL> all_day = models . BooleanField ( default = False ) <EOL> def __str__ ( self ) : <EOL> strftime = settings . SHORT_DATETIME_FORMAT <EOL> return '<STR_LIT>' % ( self . event . title , timedelta_nice_repr ( self . interval ) , date ( self . dt_start . strftime , strftime ) ) <EOL> def to_rrule ( self ) : <EOL> return rrule ( <EOL> freq = self . frequency , <EOL> interval = self . interval , <EOL> dtstart = self . begin , <EOL> until = self . finish , <EOL> ) <EOL> @ property <EOL> def freq_interval_as_timedelta ( self ) : <EOL> timedelta_frequencies = { <EOL> YEARLY : datetime . timedelta ( days = <NUM_LIT> ) , <EOL> MONTHLY : datetime . timedelta ( days = <NUM_LIT:30> ) , <EOL> WEEKLY : datetime . timedelta ( days = <NUM_LIT:7> ) , <EOL> DAILY : datetime . timedelta ( days = <NUM_LIT:1> ) , <EOL> } <EOL> return self . interval * timedelta_frequencies [ self . frequency ] <EOL> @ property <EOL> def dt_start ( self ) : <EOL> since = timezone . now ( ) <EOL> return self . to_rrule ( ) . after ( since ) <EOL> @ property <EOL> def dt_end ( self ) : <EOL> duration = self . duration <EOL> if not isinstance ( duration , datetime . timedelta ) : <EOL> duration = timedelta_parse ( duration ) <EOL> return self . dt_start + duration <EOL> @ property <EOL> def single_day ( self ) : <EOL> return self . dt_start . date ( ) == self . dt_end . date ( ) <EOL> class Alarm ( ContentManageable ) : <EOL> event = models . ForeignKey ( Event ) <EOL> trigger = models . PositiveSmallIntegerField ( _ ( "<STR_LIT>" ) , default = <NUM_LIT> ) <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % ( self . event . title , self . recipient ) <EOL> @ property <EOL> def recipient ( self ) : <EOL> full_name = self . creator . get_full_name ( ) <EOL> if full_name : <EOL> return "<STR_LIT>" % ( full_name , self . creator . email ) <EOL> return self . creator . email </s>
