Added sortable_field_name to the collection member inline for grappelli.
[philo.git] / contrib / julian / models.py
index 44b51f6..5c49c7e 100644 (file)
@@ -3,6 +3,7 @@ from django.conf.urls.defaults import url, patterns, include
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.generic import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.generic import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
+from django.contrib.sites.models import Site
 from django.core.exceptions import ValidationError, ObjectDoesNotExist
 from django.core.validators import RegexValidator
 from django.db import models
 from django.core.exceptions import ValidationError, ObjectDoesNotExist
 from django.core.validators import RegexValidator
 from django.db import models
@@ -14,16 +15,29 @@ from philo.contrib.penfield.models import FeedView, FEEDS
 from philo.exceptions import ViewCanNotProvideSubpath
 from philo.models import Tag, Entity, Page, TemplateField
 from philo.utils import ContentTypeRegistryLimiter
 from philo.exceptions import ViewCanNotProvideSubpath
 from philo.models import Tag, Entity, Page, TemplateField
 from philo.utils import ContentTypeRegistryLimiter
-import re, datetime, calendar
+import datetime, calendar
 
 
 
 
-# TODO: Could this regex more closely match the Formal Public Identifier spec?
-# http://xml.coverpages.org/tauber-fpi.html
-FPI_REGEX = re.compile(r"(|\+//|-//)[^/]+//[^/]+//[A-Z]{2}")
+__all__ = ('register_location_model', 'unregister_location_model', 'Location', 'TimedModel', 'Event', 'Calendar', 'CalendarView',)
 
 
 ICALENDAR = ICalendarFeed.mime_type
 FEEDS[ICALENDAR] = ICalendarFeed
 
 
 ICALENDAR = ICalendarFeed.mime_type
 FEEDS[ICALENDAR] = ICalendarFeed
+try:
+       DEFAULT_SITE = Site.objects.get_current()
+except:
+       DEFAULT_SITE = None
+_languages = dict(settings.LANGUAGES)
+try:
+       _languages[settings.LANGUAGE_CODE]
+       DEFAULT_LANGUAGE = settings.LANGUAGE_CODE
+except KeyError:
+       try:
+               lang = settings.LANGUAGE_CODE.split('-')[0]
+               _languages[lang]
+               DEFAULT_LANGUAGE = lang
+       except KeyError:
+               DEFAULT_LANGUAGE = None
 
 
 location_content_type_limiter = ContentTypeRegistryLimiter()
 
 
 location_content_type_limiter = ContentTypeRegistryLimiter()
@@ -65,10 +79,10 @@ class TimedModel(models.Model):
                        raise ValidationError("A %s cannot end before it starts." % self.__class__.__name__)
        
        def get_start(self):
                        raise ValidationError("A %s cannot end before it starts." % self.__class__.__name__)
        
        def get_start(self):
-               return self.start_date
+               return datetime.datetime.combine(self.start_date, self.start_time) if self.start_time else self.start_date
        
        def get_end(self):
        
        def get_end(self):
-               return self.end_date
+               return datetime.datetime.combine(self.end_date, self.end_time) if self.end_time else self.end_date
        
        class Meta:
                abstract = True
        
        class Meta:
                abstract = True
@@ -76,7 +90,17 @@ class TimedModel(models.Model):
 
 class EventManager(models.Manager):
        def get_query_set(self):
 
 class EventManager(models.Manager):
        def get_query_set(self):
-               return self.model.QuerySet(self.model)
+               return EventQuerySet(self.model)
+
+class EventQuerySet(QuerySet):
+       def upcoming(self):
+               return self.filter(start_date__gte=datetime.date.today())
+       def current(self):
+               return self.filter(start_date__lte=datetime.date.today(), end_date__gte=datetime.date.today())
+       def single_day(self):
+               return self.filter(start_date__exact=models.F('end_date'))
+       def multiday(self):
+               return self.exclude(start_date__exact=models.F('end_date'))
 
 class Event(Entity, TimedModel):
        name = models.CharField(max_length=255)
 
 class Event(Entity, TimedModel):
        name = models.CharField(max_length=255)
@@ -97,39 +121,41 @@ class Event(Entity, TimedModel):
        
        created = models.DateTimeField(auto_now_add=True)
        last_modified = models.DateTimeField(auto_now=True)
        
        created = models.DateTimeField(auto_now_add=True)
        last_modified = models.DateTimeField(auto_now=True)
-       uuid = models.TextField() # Format?
        
        
-       objects = EventManager()
+       site = models.ForeignKey(Site, default=DEFAULT_SITE)
        
        
-       class QuerySet(QuerySet):
-                       
-               def upcoming(self):
-                       return self.filter(start_date__gte=datetime.date.today())
-                       
-               def current(self):
-                       return self.filter(start_date__lte=datetime.date.today(), end_date__gte=datetime.date.today())
-                       
-               def single_day(self):
-                       return self.filter(start_date__exact=models.F('end_date'))
+       @property
+       def uuid(self):
+               return "%s@%s" % (self.created.isoformat(), getattr(self.site, 'domain', 'None'))
        
        
-               def multiday(self):
-                       return self.exclude(start_date__exact=models.F('end_date'))
+       objects = EventManager()
        
        def __unicode__(self):
                return self.name
        
        def __unicode__(self):
                return self.name
+       
+       class Meta:
+               unique_together = ('site', 'created')
 
 
 class Calendar(Entity):
        name = models.CharField(max_length=100)
        slug = models.SlugField(max_length=100)
        description = models.TextField(blank=True)
 
 
 class Calendar(Entity):
        name = models.CharField(max_length=100)
        slug = models.SlugField(max_length=100)
        description = models.TextField(blank=True)
-       events = models.ManyToManyField(Event, related_name='calendars')
+       events = models.ManyToManyField(Event, related_name='calendars', blank=True)
        
        
-       # TODO: Can we auto-generate this on save based on site id and calendar name and settings language?
-       uuid = models.TextField("Calendar UUID", unique=True, help_text="Should conform to Formal Public Identifier format. See <a href='http://en.wikipedia.org/wiki/Formal_Public_Identifier'>Wikipedia</a>.", validators=[RegexValidator(FPI_REGEX)])
+       site = models.ForeignKey(Site, default=DEFAULT_SITE)
+       language = models.CharField(max_length=5, choices=settings.LANGUAGES, default=DEFAULT_LANGUAGE)
        
        def __unicode__(self):
                return self.name
        
        def __unicode__(self):
                return self.name
+       
+       @property
+       def fpi(self):
+               # See http://xml.coverpages.org/tauber-fpi.html or ISO 9070:1991 for format information.
+               return "-//%s//%s//%s" % (self.site.name, self.name, self.language.split('-')[0].upper())
+       
+       class Meta:
+               unique_together = ('name', 'site', 'language')
 
 
 class CalendarView(FeedView):
 
 
 class CalendarView(FeedView):
@@ -385,8 +411,7 @@ class CalendarView(FeedView):
                return ""
        
        def feed_guid(self, obj):
                return ""
        
        def feed_guid(self, obj):
-               # Is this correct? Should I have a different id for different subfeeds?
-               return obj.uuid
+               return obj.fpi
        
        def description(self, obj):
                return obj.description
        
        def description(self, obj):
                return obj.description