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.db.models.query import QuerySet
from django.http import HttpResponse, Http404
from django.utils.encoding import force_unicode
from philo.contrib.julian.feedgenerator import ICalendarFeed
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
+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()
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):
- 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 EventManager(models.Manager):
+ def get_query_set(self):
+ 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)
slug = models.SlugField(max_length=255, unique_for_date='start_date')
created = models.DateTimeField(auto_now_add=True)
last_modified = models.DateTimeField(auto_now=True)
- uuid = models.TextField() # Format?
+
+ site = models.ForeignKey(Site, default=DEFAULT_SITE)
+
+ @property
+ def uuid(self):
+ return "%s@%s" % (self.created.isoformat(), getattr(self.site, 'domain', 'None'))
+
+ objects = EventManager()
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)
- 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
+
+ @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):
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