From: Harris Lapiroff Date: Tue, 5 Apr 2011 17:00:23 +0000 (-0400) Subject: Merge branch 'julian' X-Git-Tag: philo-0.9~15^2~3^2 X-Git-Url: http://git.ithinksw.org/philo.git/commitdiff_plain/bf78e0c846297a4f732ffdfc181b3c89428fd2a4?hp=e34370024b84235952bddecb46029bcfd656bdc2 Merge branch 'julian' --- diff --git a/admin/base.py b/admin/base.py index 8151461..75fa336 100644 --- a/admin/base.py +++ b/admin/base.py @@ -31,54 +31,50 @@ class AttributeInline(generic.GenericTabularInline): template = 'admin/philo/edit_inline/tabular_attribute.html' -def hide_proxy_fields(cls, attname, proxy_field_set): - val_set = set(getattr(cls, attname)) - if proxy_field_set & val_set: - cls._hidden_attributes[attname] = list(val_set) - setattr(cls, attname, list(val_set - proxy_field_set)) +# HACK to bypass model validation for proxy fields +class SpoofedHiddenFields(object): + def __init__(self, proxy_fields, value): + self.value = value + self.spoofed = list(set(value) - set(proxy_fields)) + + def __get__(self, instance, owner): + if instance is None: + return self.spoofed + return self.value + + +class SpoofedAddedFields(SpoofedHiddenFields): + def __init__(self, proxy_fields, value): + self.value = value + self.spoofed = list(set(value) | set(proxy_fields)) + + +def hide_proxy_fields(cls, attname): + val = getattr(cls, attname, []) + proxy_fields = getattr(cls, 'proxy_fields') + if val: + setattr(cls, attname, SpoofedHiddenFields(proxy_fields, val)) + +def add_proxy_fields(cls, attname): + val = getattr(cls, attname, []) + proxy_fields = getattr(cls, 'proxy_fields') + setattr(cls, attname, SpoofedAddedFields(proxy_fields, val)) class EntityAdminMetaclass(admin.ModelAdmin.__metaclass__): def __new__(cls, name, bases, attrs): - # HACK to bypass model validation for proxy fields by masking them as readonly fields new_class = super(EntityAdminMetaclass, cls).__new__(cls, name, bases, attrs) - form = getattr(new_class, 'form', None) - if form: - opts = form._meta - if issubclass(form, EntityForm) and opts.model: - proxy_fields = proxy_fields_for_entity_model(opts.model).keys() - - # Store readonly fields iff they have been declared. - if 'readonly_fields' in attrs or not hasattr(new_class, '_real_readonly_fields'): - new_class._real_readonly_fields = new_class.readonly_fields - - readonly_fields = new_class.readonly_fields - new_class.readonly_fields = list(set(readonly_fields) | set(proxy_fields)) - - # Additional HACKS to handle raw_id_fields and other attributes that the admin - # uses model._meta.get_field to validate. - new_class._hidden_attributes = {} - proxy_fields = set(proxy_fields) - hide_proxy_fields(new_class, 'raw_id_fields', proxy_fields) - #END HACK + hide_proxy_fields(new_class, 'raw_id_fields') + add_proxy_fields(new_class, 'readonly_fields') return new_class - +# END HACK class EntityAdmin(admin.ModelAdmin): __metaclass__ = EntityAdminMetaclass form = EntityForm inlines = [AttributeInline] save_on_top = True - - def __init__(self, *args, **kwargs): - # HACK PART 2 restores the actual readonly fields etc. on __init__. - if hasattr(self, '_real_readonly_fields'): - self.readonly_fields = self.__class__._real_readonly_fields - if hasattr(self, '_hidden_attributes'): - for name, value in self._hidden_attributes.items(): - setattr(self, name, value) - # END HACK - super(EntityAdmin, self).__init__(*args, **kwargs) + proxy_fields = [] def formfield_for_dbfield(self, db_field, **kwargs): """ diff --git a/contrib/julian/admin.py b/contrib/julian/admin.py index 10bc6f9..8f104e2 100644 --- a/contrib/julian/admin.py +++ b/contrib/julian/admin.py @@ -19,7 +19,7 @@ class EventAdmin(EntityAdmin): 'fields': (('start_date', 'start_time'), ('end_date', 'end_time'),), }), ('Advanced', { - 'fields': ('parent_event', 'uuid',), + 'fields': ('parent_event', 'site',), 'classes': COLLAPSE_CLASSES }) ) @@ -40,7 +40,7 @@ class CalendarAdmin(EntityAdmin): 'fields': ('name', 'description', 'events') }), ('Advanced', { - 'fields': ('slug', 'uuid'), + 'fields': ('slug', 'site', 'language',), 'classes': COLLAPSE_CLASSES }) ) @@ -70,6 +70,8 @@ class CalendarViewAdmin(EntityAdmin): 'classes': COLLAPSE_CLASSES }) ) + raw_id_fields = ('index_page', 'event_detail_page', 'timespan_page', 'tag_page', 'location_page', 'owner_page', 'location_archive_page', 'tag_archive_page', 'owner_archive_page', 'item_title_template', 'item_description_template',) + related_lookup_fields = {'fk': raw_id_fields} admin.site.register(Location, LocationAdmin) diff --git a/contrib/julian/feedgenerator.py b/contrib/julian/feedgenerator.py index 19e959d..819a273 100644 --- a/contrib/julian/feedgenerator.py +++ b/contrib/julian/feedgenerator.py @@ -41,13 +41,6 @@ ITEM_ICAL_MAP = { class ICalendarFeed(SyndicationFeed): - #def __init__(self, title, link, description, language=None, author_email=None, - # author_name=None, author_link=None, subtitle=None, categories=None, - # feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs): - # super(ICalendarFeed, self).__init__(title, link, description, language, - # author_email, author_name, author_link, subtitle, categories, - # feed_url, feed_copyright, feed_guid, ttl, **kwargs) - # mime_type = 'text/calendar' def add_item(self, *args, **kwargs): diff --git a/contrib/julian/migrations/0001_initial.py b/contrib/julian/migrations/0001_initial.py index d4864c6..3236095 100644 --- a/contrib/julian/migrations/0001_initial.py +++ b/contrib/julian/migrations/0001_initial.py @@ -12,6 +12,7 @@ class Migration(SchemaMigration): db.create_table('julian_location', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('name', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255, db_index=True)), )) db.send_create_signal('julian', ['Location']) @@ -24,14 +25,20 @@ class Migration(SchemaMigration): ('end_time', self.gf('django.db.models.fields.TimeField')(null=True, blank=True)), ('name', self.gf('django.db.models.fields.CharField')(max_length=255)), ('slug', self.gf('django.db.models.fields.SlugField')(max_length=255, db_index=True)), - ('location_content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), - ('location_pk', self.gf('django.db.models.fields.TextField')()), + ('location_content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True, blank=True)), + ('location_pk', self.gf('django.db.models.fields.TextField')(blank=True)), ('description', self.gf('philo.models.fields.TemplateField')()), ('parent_event', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['julian.Event'], null=True, blank=True)), - ('owner', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + ('owner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='owned_events', to=orm['auth.User'])), + ('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + ('site', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['sites.Site'])), )) db.send_create_signal('julian', ['Event']) + # Adding unique constraint on 'Event', fields ['site', 'created'] + db.create_unique('julian_event', ['site_id', 'created']) + # Adding M2M table for field tags on 'Event' db.create_table('julian_event_tags', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), @@ -44,10 +51,16 @@ class Migration(SchemaMigration): db.create_table('julian_calendar', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('name', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('uuid', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)), + ('slug', self.gf('django.db.models.fields.SlugField')(max_length=100, db_index=True)), + ('description', self.gf('django.db.models.fields.TextField')(blank=True)), + ('site', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['sites.Site'])), + ('language', self.gf('django.db.models.fields.CharField')(default='en', max_length=5)), )) db.send_create_signal('julian', ['Calendar']) + # Adding unique constraint on 'Calendar', fields ['name', 'site', 'language'] + db.create_unique('julian_calendar', ['name', 'site_id', 'language']) + # Adding M2M table for field events on 'Calendar' db.create_table('julian_calendar_events', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), @@ -56,9 +69,41 @@ class Migration(SchemaMigration): )) db.create_unique('julian_calendar_events', ['calendar_id', 'event_id']) + # Adding model 'CalendarView' + db.create_table('julian_calendarview', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('feed_type', self.gf('django.db.models.fields.CharField')(default='text/calendar', max_length=50)), + ('feed_suffix', self.gf('django.db.models.fields.CharField')(default='feed', max_length=255)), + ('feeds_enabled', self.gf('django.db.models.fields.BooleanField')(default=True)), + ('feed_length', self.gf('django.db.models.fields.PositiveIntegerField')(default=15, null=True, blank=True)), + ('item_title_template', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='julian_calendarview_title_related', null=True, to=orm['philo.Template'])), + ('item_description_template', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='julian_calendarview_description_related', null=True, to=orm['philo.Template'])), + ('calendar', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['julian.Calendar'])), + ('index_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_index_related', to=orm['philo.Page'])), + ('event_detail_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_detail_related', to=orm['philo.Page'])), + ('timespan_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_timespan_related', null=True, to=orm['philo.Page'])), + ('tag_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_tag_related', null=True, to=orm['philo.Page'])), + ('location_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_location_related', null=True, to=orm['philo.Page'])), + ('owner_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_owner_related', null=True, to=orm['philo.Page'])), + ('tag_archive_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_tag_archive_related', null=True, to=orm['philo.Page'])), + ('location_archive_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_location_archive_related', null=True, to=orm['philo.Page'])), + ('owner_archive_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_owner_archive_related', null=True, to=orm['philo.Page'])), + ('tag_permalink_base', self.gf('django.db.models.fields.CharField')(default='tags', max_length=30)), + ('owner_permalink_base', self.gf('django.db.models.fields.CharField')(default='owners', max_length=30)), + ('location_permalink_base', self.gf('django.db.models.fields.CharField')(default='locations', max_length=30)), + ('events_per_page', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)), + )) + db.send_create_signal('julian', ['CalendarView']) + def backwards(self, orm): + # Removing unique constraint on 'Calendar', fields ['name', 'site', 'language'] + db.delete_unique('julian_calendar', ['name', 'site_id', 'language']) + + # Removing unique constraint on 'Event', fields ['site', 'created'] + db.delete_unique('julian_event', ['site_id', 'created']) + # Deleting model 'Location' db.delete_table('julian_location') @@ -74,6 +119,9 @@ class Migration(SchemaMigration): # Removing M2M table for field events on 'Calendar' db.delete_table('julian_calendar_events') + # Deleting model 'CalendarView' + db.delete_table('julian_calendarview') + models = { 'auth.group': { @@ -83,7 +131,7 @@ class Migration(SchemaMigration): 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) }, 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), @@ -96,9 +144,9 @@ class Migration(SchemaMigration): 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), @@ -106,39 +154,78 @@ class Migration(SchemaMigration): 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) }, 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) }, 'julian.calendar': { - 'Meta': {'object_name': 'Calendar'}, - 'events': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'calendars'", 'symmetrical': 'False', 'to': "orm['julian.Event']"}), + 'Meta': {'unique_together': "(('name', 'site', 'language'),)", 'object_name': 'Calendar'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'events': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'calendars'", 'blank': 'True', 'to': "orm['julian.Event']"}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '5'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}) + }, + 'julian.calendarview': { + 'Meta': {'object_name': 'CalendarView'}, + 'calendar': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Calendar']"}), + 'event_detail_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_detail_related'", 'to': "orm['philo.Page']"}), + 'events_per_page': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'feed_length': ('django.db.models.fields.PositiveIntegerField', [], {'default': '15', 'null': 'True', 'blank': 'True'}), + 'feed_suffix': ('django.db.models.fields.CharField', [], {'default': "'feed'", 'max_length': '255'}), + 'feed_type': ('django.db.models.fields.CharField', [], {'default': "'text/calendar'", 'max_length': '50'}), + 'feeds_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_index_related'", 'to': "orm['philo.Page']"}), + 'item_description_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_calendarview_description_related'", 'null': 'True', 'to': "orm['philo.Template']"}), + 'item_title_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_calendarview_title_related'", 'null': 'True', 'to': "orm['philo.Template']"}), + 'location_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_location_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), + 'location_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_location_related'", 'null': 'True', 'to': "orm['philo.Page']"}), + 'location_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'locations'", 'max_length': '30'}), + 'owner_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_owner_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), + 'owner_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_owner_related'", 'null': 'True', 'to': "orm['philo.Page']"}), + 'owner_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'owners'", 'max_length': '30'}), + 'tag_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_tag_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), + 'tag_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_tag_related'", 'null': 'True', 'to': "orm['philo.Page']"}), + 'tag_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'tags'", 'max_length': '30'}), + 'timespan_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_timespan_related'", 'null': 'True', 'to': "orm['philo.Page']"}) }, 'julian.event': { - 'Meta': {'object_name': 'Event'}, + 'Meta': {'unique_together': "(('site', 'created'),)", 'object_name': 'Event'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), 'description': ('philo.models.fields.TemplateField', [], {}), 'end_date': ('django.db.models.fields.DateField', [], {}), 'end_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'location_pk': ('django.db.models.fields.TextField', [], {}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), + 'location_pk': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_events'", 'to': "orm['auth.User']"}), 'parent_event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Event']", 'null': 'True', 'blank': 'True'}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']"}), 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), 'start_date': ('django.db.models.fields.DateField', [], {}), 'start_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['philo.Tag']", 'null': 'True', 'blank': 'True'}) + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'events'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['philo.Tag']"}) }, 'julian.location': { 'Meta': {'object_name': 'Location'}, 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) + }, + 'oberlin.locationcoordinates': { + 'Meta': {'unique_together': "(('location_ct', 'location_pk'),)", 'object_name': 'LocationCoordinates'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'latitude': ('django.db.models.fields.FloatField', [], {}), + 'location_ct': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'location_pk': ('django.db.models.fields.TextField', [], {}), + 'longitude': ('django.db.models.fields.FloatField', [], {}) }, 'philo.attribute': { 'Meta': {'unique_together': "(('key', 'entity_content_type', 'entity_object_id'), ('value_content_type', 'value_object_id'))", 'object_name': 'Attribute'}, @@ -149,11 +236,50 @@ class Migration(SchemaMigration): 'value_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attribute_value_set'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), 'value_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) }, + 'philo.node': { + 'Meta': {'object_name': 'Node'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Node']"}), + 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), + 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'view_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'node_view_set'", 'to': "orm['contenttypes.ContentType']"}), + 'view_object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) + }, + 'philo.page': { + 'Meta': {'object_name': 'Page'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pages'", 'to': "orm['philo.Template']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, 'philo.tag': { - 'Meta': {'object_name': 'Tag'}, + 'Meta': {'ordering': "('name',)", 'object_name': 'Tag'}, 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) + }, + 'philo.template': { + 'Meta': {'object_name': 'Template'}, + 'code': ('philo.models.fields.TemplateField', [], {}), + 'documentation': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'mimetype': ('django.db.models.fields.CharField', [], {'default': "'text/html'", 'max_length': '255'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Template']"}), + 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), + 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) + }, + 'sites.site': { + 'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'root_node': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'sites'", 'null': 'True', 'to': "orm['philo.Node']"}) } } diff --git a/contrib/julian/migrations/0002_auto__add_field_event_created__add_field_event_last_modified__add_fiel.py b/contrib/julian/migrations/0002_auto__add_field_event_created__add_field_event_last_modified__add_fiel.py deleted file mode 100644 index c0c2fad..0000000 --- a/contrib/julian/migrations/0002_auto__add_field_event_created__add_field_event_last_modified__add_fiel.py +++ /dev/null @@ -1,138 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'Event.created' - db.add_column('julian_event', 'created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.datetime(2011, 2, 10, 15, 14, 35, 721341), blank=True), keep_default=False) - - # Adding field 'Event.last_modified' - db.add_column('julian_event', 'last_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, default=datetime.datetime(2011, 2, 10, 15, 14, 42, 370147), blank=True), keep_default=False) - - # Adding field 'Event.uuid' - db.add_column('julian_event', 'uuid', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False) - - # Adding field 'Calendar.slug' - db.add_column('julian_calendar', 'slug', self.gf('django.db.models.fields.SlugField')(default='', max_length=100, db_index=True), keep_default=False) - - # Adding field 'Calendar.description' - db.add_column('julian_calendar', 'description', self.gf('django.db.models.fields.TextField')(default='', blank=True), keep_default=False) - - # Changing field 'Calendar.uuid' - db.alter_column('julian_calendar', 'uuid', self.gf('django.db.models.fields.TextField')(unique=True)) - - - def backwards(self, orm): - - # Deleting field 'Event.created' - db.delete_column('julian_event', 'created') - - # Deleting field 'Event.last_modified' - db.delete_column('julian_event', 'last_modified') - - # Deleting field 'Event.uuid' - db.delete_column('julian_event', 'uuid') - - # Deleting field 'Calendar.slug' - db.delete_column('julian_calendar', 'slug') - - # Deleting field 'Calendar.description' - db.delete_column('julian_calendar', 'description') - - # Changing field 'Calendar.uuid' - db.alter_column('julian_calendar', 'uuid', self.gf('django.db.models.fields.CharField')(max_length=100, unique=True)) - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'julian.calendar': { - 'Meta': {'object_name': 'Calendar'}, - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'events': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'calendars'", 'symmetrical': 'False', 'to': "orm['julian.Event']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {'unique': 'True'}) - }, - 'julian.event': { - 'Meta': {'object_name': 'Event'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'description': ('philo.models.fields.TemplateField', [], {}), - 'end_date': ('django.db.models.fields.DateField', [], {}), - 'end_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'location_pk': ('django.db.models.fields.TextField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'parent_event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Event']", 'null': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'start_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['philo.Tag']", 'null': 'True', 'blank': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {}) - }, - 'julian.location': { - 'Meta': {'object_name': 'Location'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'philo.attribute': { - 'Meta': {'unique_together': "(('key', 'entity_content_type', 'entity_object_id'), ('value_content_type', 'value_object_id'))", 'object_name': 'Attribute'}, - 'entity_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_entity_set'", 'to': "orm['contenttypes.ContentType']"}), - 'entity_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), - 'value_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attribute_value_set'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'value_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) - }, - 'philo.tag': { - 'Meta': {'object_name': 'Tag'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - } - } - - complete_apps = ['julian'] diff --git a/contrib/julian/migrations/0003_auto__add_icalendarfeedview.py b/contrib/julian/migrations/0003_auto__add_icalendarfeedview.py deleted file mode 100644 index 0f31330..0000000 --- a/contrib/julian/migrations/0003_auto__add_icalendarfeedview.py +++ /dev/null @@ -1,153 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding model 'ICalendarFeedView' - db.create_table('julian_icalendarfeedview', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('feed_type', self.gf('django.db.models.fields.CharField')(default='application/atom+xml', max_length=50)), - ('feed_suffix', self.gf('django.db.models.fields.CharField')(default='feed', max_length=255)), - ('feeds_enabled', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True)), - ('item_title_template', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='julian_icalendarfeedview_title_related', null=True, to=orm['philo.Template'])), - ('item_description_template', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='julian_icalendarfeedview_description_related', null=True, to=orm['philo.Template'])), - ('calendar', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['julian.Calendar'])), - )) - db.send_create_signal('julian', ['ICalendarFeedView']) - - - def backwards(self, orm): - - # Deleting model 'ICalendarFeedView' - db.delete_table('julian_icalendarfeedview') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'julian.calendar': { - 'Meta': {'object_name': 'Calendar'}, - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'events': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'calendars'", 'symmetrical': 'False', 'to': "orm['julian.Event']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {'unique': 'True'}) - }, - 'julian.event': { - 'Meta': {'object_name': 'Event'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'description': ('philo.models.fields.TemplateField', [], {}), - 'end_date': ('django.db.models.fields.DateField', [], {}), - 'end_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'location_pk': ('django.db.models.fields.TextField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'parent_event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Event']", 'null': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'start_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['philo.Tag']", 'null': 'True', 'blank': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {}) - }, - 'julian.icalendarfeedview': { - 'Meta': {'object_name': 'ICalendarFeedView'}, - 'calendar': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Calendar']"}), - 'feed_suffix': ('django.db.models.fields.CharField', [], {'default': "'feed'", 'max_length': '255'}), - 'feed_type': ('django.db.models.fields.CharField', [], {'default': "'application/atom+xml'", 'max_length': '50'}), - 'feeds_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'item_description_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_icalendarfeedview_description_related'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'item_title_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_icalendarfeedview_title_related'", 'null': 'True', 'to': "orm['philo.Template']"}) - }, - 'julian.location': { - 'Meta': {'object_name': 'Location'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'philo.attribute': { - 'Meta': {'unique_together': "(('key', 'entity_content_type', 'entity_object_id'), ('value_content_type', 'value_object_id'))", 'object_name': 'Attribute'}, - 'entity_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_entity_set'", 'to': "orm['contenttypes.ContentType']"}), - 'entity_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), - 'value_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attribute_value_set'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'value_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) - }, - 'philo.node': { - 'Meta': {'object_name': 'Node'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Node']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'view_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'node_view_set'", 'to': "orm['contenttypes.ContentType']"}), - 'view_object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) - }, - 'philo.tag': { - 'Meta': {'object_name': 'Tag'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - }, - 'philo.template': { - 'Meta': {'object_name': 'Template'}, - 'code': ('philo.models.fields.TemplateField', [], {}), - 'documentation': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'mimetype': ('django.db.models.fields.CharField', [], {'default': "'text/html'", 'max_length': '255'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) - } - } - - complete_apps = ['julian'] diff --git a/contrib/julian/migrations/0004_auto__chg_field_event_location_content_type__chg_field_event_location_.py b/contrib/julian/migrations/0004_auto__chg_field_event_location_content_type__chg_field_event_location_.py deleted file mode 100644 index 42b5702..0000000 --- a/contrib/julian/migrations/0004_auto__chg_field_event_location_content_type__chg_field_event_location_.py +++ /dev/null @@ -1,150 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Changing field 'Event.location_content_type' - db.alter_column('julian_event', 'location_content_type_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'], null=True, blank=True)) - - # Changing field 'Event.location_pk' - db.alter_column('julian_event', 'location_pk', self.gf('django.db.models.fields.TextField')(blank=True)) - - - def backwards(self, orm): - - # Changing field 'Event.location_content_type' - db.alter_column('julian_event', 'location_content_type_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])) - - # Changing field 'Event.location_pk' - db.alter_column('julian_event', 'location_pk', self.gf('django.db.models.fields.TextField')()) - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'julian.calendar': { - 'Meta': {'object_name': 'Calendar'}, - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'events': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'calendars'", 'symmetrical': 'False', 'to': "orm['julian.Event']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {'unique': 'True'}) - }, - 'julian.event': { - 'Meta': {'object_name': 'Event'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'description': ('philo.models.fields.TemplateField', [], {}), - 'end_date': ('django.db.models.fields.DateField', [], {}), - 'end_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'location_pk': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'parent_event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Event']", 'null': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'start_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['philo.Tag']", 'null': 'True', 'blank': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {}) - }, - 'julian.icalendarfeedview': { - 'Meta': {'object_name': 'ICalendarFeedView'}, - 'calendar': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Calendar']"}), - 'feed_suffix': ('django.db.models.fields.CharField', [], {'default': "'feed'", 'max_length': '255'}), - 'feed_type': ('django.db.models.fields.CharField', [], {'default': "'application/atom+xml'", 'max_length': '50'}), - 'feeds_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'item_description_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_icalendarfeedview_description_related'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'item_title_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_icalendarfeedview_title_related'", 'null': 'True', 'to': "orm['philo.Template']"}) - }, - 'julian.location': { - 'Meta': {'object_name': 'Location'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'philo.attribute': { - 'Meta': {'unique_together': "(('key', 'entity_content_type', 'entity_object_id'), ('value_content_type', 'value_object_id'))", 'object_name': 'Attribute'}, - 'entity_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_entity_set'", 'to': "orm['contenttypes.ContentType']"}), - 'entity_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), - 'value_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attribute_value_set'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'value_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) - }, - 'philo.node': { - 'Meta': {'object_name': 'Node'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Node']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'view_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'node_view_set'", 'to': "orm['contenttypes.ContentType']"}), - 'view_object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) - }, - 'philo.tag': { - 'Meta': {'object_name': 'Tag'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - }, - 'philo.template': { - 'Meta': {'object_name': 'Template'}, - 'code': ('philo.models.fields.TemplateField', [], {}), - 'documentation': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'mimetype': ('django.db.models.fields.CharField', [], {'default': "'text/html'", 'max_length': '255'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) - } - } - - complete_apps = ['julian'] diff --git a/contrib/julian/migrations/0005_auto__del_icalendarfeedview__add_calendarview__add_field_location_slug.py b/contrib/julian/migrations/0005_auto__del_icalendarfeedview__add_calendarview__add_field_location_slug.py deleted file mode 100644 index e3bae80..0000000 --- a/contrib/julian/migrations/0005_auto__del_icalendarfeedview__add_calendarview__add_field_location_slug.py +++ /dev/null @@ -1,205 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Deleting model 'ICalendarFeedView' - db.delete_table('julian_icalendarfeedview') - - # Adding model 'CalendarView' - db.create_table('julian_calendarview', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('feed_type', self.gf('django.db.models.fields.CharField')(default='text/calendar', max_length=50)), - ('feed_suffix', self.gf('django.db.models.fields.CharField')(default='feed', max_length=255)), - ('feeds_enabled', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True)), - ('item_title_template', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='julian_calendarview_title_related', null=True, to=orm['philo.Template'])), - ('item_description_template', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='julian_calendarview_description_related', null=True, to=orm['philo.Template'])), - ('calendar', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['julian.Calendar'])), - ('index_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_index_related', to=orm['philo.Page'])), - ('timespan_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_timespan_related', to=orm['philo.Page'])), - ('event_detail_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_detail_related', to=orm['philo.Page'])), - ('tag_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_tag_related', to=orm['philo.Page'])), - ('location_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_location_related', to=orm['philo.Page'])), - ('owner_page', self.gf('django.db.models.fields.related.ForeignKey')(related_name='calendar_owner_related', to=orm['philo.Page'])), - ('tag_archive_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_tag_archive_related', null=True, to=orm['philo.Page'])), - ('location_archive_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_location_archive_related', null=True, to=orm['philo.Page'])), - ('owner_archive_page', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='calendar_owner_archive_related', null=True, to=orm['philo.Page'])), - ('tag_permalink_base', self.gf('django.db.models.fields.CharField')(default='tags', max_length=30)), - ('owner_permalink_base', self.gf('django.db.models.fields.CharField')(default='owner', max_length=30)), - ('location_permalink_base', self.gf('django.db.models.fields.CharField')(default='location', max_length=30)), - )) - db.send_create_signal('julian', ['CalendarView']) - - # Adding field 'Location.slug' - db.add_column('julian_location', 'slug', self.gf('django.db.models.fields.SlugField')(default='slug', unique=True, max_length=255, db_index=True), keep_default=False) - - - def backwards(self, orm): - - # Adding model 'ICalendarFeedView' - db.create_table('julian_icalendarfeedview', ( - ('item_title_template', self.gf('django.db.models.fields.related.ForeignKey')(related_name='julian_icalendarfeedview_title_related', null=True, to=orm['philo.Template'], blank=True)), - ('feed_type', self.gf('django.db.models.fields.CharField')(default='application/atom+xml', max_length=50)), - ('item_description_template', self.gf('django.db.models.fields.related.ForeignKey')(related_name='julian_icalendarfeedview_description_related', null=True, to=orm['philo.Template'], blank=True)), - ('feeds_enabled', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True)), - ('calendar', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['julian.Calendar'])), - ('feed_suffix', self.gf('django.db.models.fields.CharField')(default='feed', max_length=255)), - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - )) - db.send_create_signal('julian', ['ICalendarFeedView']) - - # Deleting model 'CalendarView' - db.delete_table('julian_calendarview') - - # Deleting field 'Location.slug' - db.delete_column('julian_location', 'slug') - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'julian.calendar': { - 'Meta': {'object_name': 'Calendar'}, - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'events': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'calendars'", 'symmetrical': 'False', 'to': "orm['julian.Event']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {'unique': 'True'}) - }, - 'julian.calendarview': { - 'Meta': {'object_name': 'CalendarView'}, - 'calendar': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Calendar']"}), - 'event_detail_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_detail_related'", 'to': "orm['philo.Page']"}), - 'feed_suffix': ('django.db.models.fields.CharField', [], {'default': "'feed'", 'max_length': '255'}), - 'feed_type': ('django.db.models.fields.CharField', [], {'default': "'text/calendar'", 'max_length': '50'}), - 'feeds_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_index_related'", 'to': "orm['philo.Page']"}), - 'item_description_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_calendarview_description_related'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'item_title_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_calendarview_title_related'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'location_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_location_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'location_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_location_related'", 'to': "orm['philo.Page']"}), - 'location_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'location'", 'max_length': '30'}), - 'owner_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_owner_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'owner_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_owner_related'", 'to': "orm['philo.Page']"}), - 'owner_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'owner'", 'max_length': '30'}), - 'tag_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_tag_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'tag_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_tag_related'", 'to': "orm['philo.Page']"}), - 'tag_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'tags'", 'max_length': '30'}), - 'timespan_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_timespan_related'", 'to': "orm['philo.Page']"}) - }, - 'julian.event': { - 'Meta': {'object_name': 'Event'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'description': ('philo.models.fields.TemplateField', [], {}), - 'end_date': ('django.db.models.fields.DateField', [], {}), - 'end_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'location_pk': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'parent_event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Event']", 'null': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'start_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'events'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['philo.Tag']"}), - 'uuid': ('django.db.models.fields.TextField', [], {}) - }, - 'julian.location': { - 'Meta': {'object_name': 'Location'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - }, - 'philo.attribute': { - 'Meta': {'unique_together': "(('key', 'entity_content_type', 'entity_object_id'), ('value_content_type', 'value_object_id'))", 'object_name': 'Attribute'}, - 'entity_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_entity_set'", 'to': "orm['contenttypes.ContentType']"}), - 'entity_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), - 'value_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attribute_value_set'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'value_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) - }, - 'philo.node': { - 'Meta': {'object_name': 'Node'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Node']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'view_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'node_view_set'", 'to': "orm['contenttypes.ContentType']"}), - 'view_object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) - }, - 'philo.page': { - 'Meta': {'object_name': 'Page'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pages'", 'to': "orm['philo.Template']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'philo.tag': { - 'Meta': {'object_name': 'Tag'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - }, - 'philo.template': { - 'Meta': {'object_name': 'Template'}, - 'code': ('philo.models.fields.TemplateField', [], {}), - 'documentation': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'mimetype': ('django.db.models.fields.CharField', [], {'default': "'text/html'", 'max_length': '255'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) - } - } - - complete_apps = ['julian'] diff --git a/contrib/julian/migrations/0006_auto__add_field_calendarview_events_per_page__chg_field_calendarview_t.py b/contrib/julian/migrations/0006_auto__add_field_calendarview_events_per_page__chg_field_calendarview_t.py deleted file mode 100644 index b561219..0000000 --- a/contrib/julian/migrations/0006_auto__add_field_calendarview_events_per_page__chg_field_calendarview_t.py +++ /dev/null @@ -1,188 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'CalendarView.events_per_page' - db.add_column('julian_calendarview', 'events_per_page', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True), keep_default=False) - - # Changing field 'CalendarView.timespan_page' - db.alter_column('julian_calendarview', 'timespan_page_id', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, null=True, to=orm['philo.Page'])) - - # Changing field 'CalendarView.owner_page' - db.alter_column('julian_calendarview', 'owner_page_id', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, null=True, to=orm['philo.Page'])) - - # Changing field 'CalendarView.location_page' - db.alter_column('julian_calendarview', 'location_page_id', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, null=True, to=orm['philo.Page'])) - - # Changing field 'CalendarView.tag_page' - db.alter_column('julian_calendarview', 'tag_page_id', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, null=True, to=orm['philo.Page'])) - - - def backwards(self, orm): - - # Deleting field 'CalendarView.events_per_page' - db.delete_column('julian_calendarview', 'events_per_page') - - # Changing field 'CalendarView.timespan_page' - db.alter_column('julian_calendarview', 'timespan_page_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['philo.Page'])) - - # Changing field 'CalendarView.owner_page' - db.alter_column('julian_calendarview', 'owner_page_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['philo.Page'])) - - # Changing field 'CalendarView.location_page' - db.alter_column('julian_calendarview', 'location_page_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['philo.Page'])) - - # Changing field 'CalendarView.tag_page' - db.alter_column('julian_calendarview', 'tag_page_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['philo.Page'])) - - - models = { - 'auth.group': { - 'Meta': {'object_name': 'Group'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), - 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) - }, - 'auth.permission': { - 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, - 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'auth.user': { - 'Meta': {'object_name': 'User'}, - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), - 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), - 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) - }, - 'contenttypes.contenttype': { - 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'julian.calendar': { - 'Meta': {'object_name': 'Calendar'}, - 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'events': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'calendars'", 'symmetrical': 'False', 'to': "orm['julian.Event']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '100', 'db_index': 'True'}), - 'uuid': ('django.db.models.fields.TextField', [], {'unique': 'True'}) - }, - 'julian.calendarview': { - 'Meta': {'object_name': 'CalendarView'}, - 'calendar': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Calendar']"}), - 'event_detail_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_detail_related'", 'to': "orm['philo.Page']"}), - 'events_per_page': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'feed_suffix': ('django.db.models.fields.CharField', [], {'default': "'feed'", 'max_length': '255'}), - 'feed_type': ('django.db.models.fields.CharField', [], {'default': "'text/calendar'", 'max_length': '50'}), - 'feeds_enabled': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'index_page': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'calendar_index_related'", 'to': "orm['philo.Page']"}), - 'item_description_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_calendarview_description_related'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'item_title_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'julian_calendarview_title_related'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'location_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_location_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'location_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_location_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'location_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'location'", 'max_length': '30'}), - 'owner_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_owner_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'owner_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_owner_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'owner_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'owner'", 'max_length': '30'}), - 'tag_archive_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_tag_archive_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'tag_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_tag_related'", 'null': 'True', 'to': "orm['philo.Page']"}), - 'tag_permalink_base': ('django.db.models.fields.CharField', [], {'default': "'tags'", 'max_length': '30'}), - 'timespan_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'calendar_timespan_related'", 'null': 'True', 'to': "orm['philo.Page']"}) - }, - 'julian.event': { - 'Meta': {'object_name': 'Event'}, - 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'description': ('philo.models.fields.TemplateField', [], {}), - 'end_date': ('django.db.models.fields.DateField', [], {}), - 'end_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), - 'location_content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), - 'location_pk': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'parent_event': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['julian.Event']", 'null': 'True', 'blank': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'start_date': ('django.db.models.fields.DateField', [], {}), - 'start_time': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}), - 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'events'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['philo.Tag']"}), - 'uuid': ('django.db.models.fields.TextField', [], {}) - }, - 'julian.location': { - 'Meta': {'object_name': 'Location'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - }, - 'philo.attribute': { - 'Meta': {'unique_together': "(('key', 'entity_content_type', 'entity_object_id'), ('value_content_type', 'value_object_id'))", 'object_name': 'Attribute'}, - 'entity_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attribute_entity_set'", 'to': "orm['contenttypes.ContentType']"}), - 'entity_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), - 'value_content_type': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'attribute_value_set'", 'null': 'True', 'to': "orm['contenttypes.ContentType']"}), - 'value_object_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}) - }, - 'philo.node': { - 'Meta': {'object_name': 'Node'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Node']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'view_content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'node_view_set'", 'to': "orm['contenttypes.ContentType']"}), - 'view_object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) - }, - 'philo.page': { - 'Meta': {'object_name': 'Page'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pages'", 'to': "orm['philo.Template']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) - }, - 'philo.tag': { - 'Meta': {'object_name': 'Tag'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}) - }, - 'philo.template': { - 'Meta': {'object_name': 'Template'}, - 'code': ('philo.models.fields.TemplateField', [], {}), - 'documentation': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'mimetype': ('django.db.models.fields.CharField', [], {'default': "'text/html'", 'max_length': '255'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['philo.Template']"}), - 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '255', 'db_index': 'True'}), - 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) - } - } - - complete_apps = ['julian'] diff --git a/contrib/julian/models.py b/contrib/julian/models.py index c1682cc..5c49c7e 100644 --- a/contrib/julian/models.py +++ b/contrib/julian/models.py @@ -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.sites.models import Site 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 -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() @@ -107,25 +121,41 @@ class Event(Entity, TimedModel): 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 Wikipedia.", 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): @@ -381,8 +411,7 @@ 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 diff --git a/contrib/shipherd/templatetags/shipherd.py b/contrib/shipherd/templatetags/shipherd.py index 57fb020..1413bdf 100644 --- a/contrib/shipherd/templatetags/shipherd.py +++ b/contrib/shipherd/templatetags/shipherd.py @@ -167,6 +167,4 @@ def navigation_host(node, key): try: return Navigation.objects.filter(node__in=node.get_ancestors(include_self=True), key=key).order_by('-node__level')[0].node except: - if settings.TEMPLATE_DEBUG: - raise return node \ No newline at end of file diff --git a/contrib/sobol/admin.py b/contrib/sobol/admin.py index 504cde2..87dd39a 100644 --- a/contrib/sobol/admin.py +++ b/contrib/sobol/admin.py @@ -6,10 +6,10 @@ from django.db.models import Count from django.http import HttpResponseRedirect, Http404 from django.shortcuts import render_to_response from django.template import RequestContext -from django.utils.functional import update_wrapper from django.utils.translation import ugettext_lazy as _ from philo.admin import EntityAdmin from philo.contrib.sobol.models import Search, ResultURL, SearchView +from functools import update_wrapper class ResultURLInline(admin.TabularInline): diff --git a/contrib/sobol/models.py b/contrib/sobol/models.py index b653c09..e4e4202 100644 --- a/contrib/sobol/models.py +++ b/contrib/sobol/models.py @@ -130,13 +130,13 @@ class Click(models.Model): class SearchView(MultiView): results_page = models.ForeignKey(Page, related_name='search_results_related') searches = SlugMultipleChoiceField(choices=registry.iterchoices()) - enable_ajax_api = models.BooleanField("Enable AJAX API", default=True) + enable_ajax_api = models.BooleanField("Enable AJAX API", default=True, help_text="Search results will be available only by AJAX, not as template variables.") placeholder_text = models.CharField(max_length=75, default="Search") search_form = SearchForm def __unicode__(self): - return u"%s (%s)" % (self.placeholder_text, u", ".join([display for slug, display in registry.iterchoices()])) + return u"%s (%s)" % (self.placeholder_text, u", ".join([display for slug, display in registry.iterchoices() if slug in self.searches])) def get_reverse_params(self, obj): raise ViewCanNotProvideSubpath @@ -198,7 +198,7 @@ class SearchView(MultiView): }) else: context.update({ - 'searches': [{'verbose_name': verbose_name, 'url': self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node)} for slug, verbose_name in registry.iterchoices()] + 'searches': [{'verbose_name': verbose_name, 'url': self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node)} for slug, verbose_name in registry.iterchoices() if slug in self.searches] }) else: form = SearchForm() diff --git a/contrib/sobol/search.py b/contrib/sobol/search.py index 36c2b5d..4f89e76 100644 --- a/contrib/sobol/search.py +++ b/contrib/sobol/search.py @@ -361,7 +361,7 @@ else: def parse_response(self, response, limit=None): strainer = self.strainer soup = BeautifulSoup(response, parseOnlyThese=strainer) - return self.parse_results(soup[:limit]) + return self.parse_results(soup.findAll(recursive=False, limit=limit)) def parse_results(self, results): """ diff --git a/contrib/sobol/utils.py b/contrib/sobol/utils.py index 723a463..3c5e537 100644 --- a/contrib/sobol/utils.py +++ b/contrib/sobol/utils.py @@ -1,8 +1,8 @@ from django.conf import settings from django.http import QueryDict from django.utils.encoding import smart_str -from django.utils.hashcompat import sha_constructor from django.utils.http import urlquote_plus, urlquote +from hashlib import sha1 SEARCH_ARG_GET_KEY = 'q' @@ -11,7 +11,7 @@ HASH_REDIRECT_GET_KEY = 's' def make_redirect_hash(search_arg, url): - return sha_constructor(smart_str(search_arg + url + settings.SECRET_KEY)).hexdigest()[::2] + return sha1(smart_str(search_arg + url + settings.SECRET_KEY)).hexdigest()[::2] def check_redirect_hash(hash, search_arg, url): diff --git a/contrib/waldo/tokens.py b/contrib/waldo/tokens.py index 95ce0c0..80f0b11 100644 --- a/contrib/waldo/tokens.py +++ b/contrib/waldo/tokens.py @@ -7,6 +7,7 @@ from datetime import date from django.conf import settings from django.utils.http import int_to_base36, base36_to_int from django.contrib.auth.tokens import PasswordResetTokenGenerator +from hashlib import sha1 REGISTRATION_TIMEOUT_DAYS = getattr(settings, 'WALDO_REGISTRATION_TIMEOUT_DAYS', 1) @@ -52,8 +53,7 @@ class RegistrationTokenGenerator(PasswordResetTokenGenerator): # By hashing on the internal state of the user and using state that is # sure to change, we produce a hash that will be invalid as soon as it # is used. - from django.utils.hashcompat import sha_constructor - hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) + unicode(user.is_active) + user.last_login.strftime('%Y-%m-%d %H:%M:%S') + unicode(timestamp)).hexdigest()[::2] + hash = sha1(settings.SECRET_KEY + unicode(user.id) + unicode(user.is_active) + user.last_login.strftime('%Y-%m-%d %H:%M:%S') + unicode(timestamp)).hexdigest()[::2] return '%s-%s' % (ts_b36, hash) @@ -98,8 +98,7 @@ class EmailTokenGenerator(PasswordResetTokenGenerator): def _make_token_with_timestamp(self, user, email, timestamp): ts_b36 = int_to_base36(timestamp) - from django.utils.hashcompat import sha_constructor - hash = sha_constructor(settings.SECRET_KEY + unicode(user.id) + user.email + email + unicode(timestamp)).hexdigest()[::2] + hash = sha1(settings.SECRET_KEY + unicode(user.id) + user.email + email + unicode(timestamp)).hexdigest()[::2] return '%s-%s' % (ts_b36, hash) diff --git a/forms/entities.py b/forms/entities.py index b6259a3..e781128 100644 --- a/forms/entities.py +++ b/forms/entities.py @@ -1,4 +1,4 @@ -from django.forms.models import ModelFormMetaclass, ModelForm +from django.forms.models import ModelFormMetaclass, ModelForm, ModelFormOptions from django.utils.datastructures import SortedDict from philo.utils import fattr @@ -6,7 +6,7 @@ from philo.utils import fattr __all__ = ('EntityForm',) -def proxy_fields_for_entity_model(entity_model, fields=None, exclude=None, widgets=None, formfield_callback=lambda f, **kwargs: f.formfield(**kwargs)): +def proxy_fields_for_entity_model(entity_model, fields=None, exclude=None, widgets=None, formfield_callback=None): field_list = [] ignored = [] opts = entity_model._entity_meta @@ -21,7 +21,14 @@ def proxy_fields_for_entity_model(entity_model, fields=None, exclude=None, widge kwargs = {'widget': widgets[f.name]} else: kwargs = {} - formfield = formfield_callback(f, **kwargs) + + if formfield_callback is None: + formfield = f.formfield(**kwargs) + elif not callable(formfield_callback): + raise TypeError('formfield_callback must be a function or callable') + else: + formfield = formfield_callback(f, **kwargs) + if formfield: field_list.append((f.name, formfield)) else: @@ -35,31 +42,59 @@ def proxy_fields_for_entity_model(entity_model, fields=None, exclude=None, widge return field_dict -# BEGIN HACK - This will not be required after http://code.djangoproject.com/ticket/14082 has been resolved - -class EntityFormBase(ModelForm): - pass +# HACK until http://code.djangoproject.com/ticket/14082 is resolved. +_old = ModelFormMetaclass.__new__ +def _new(cls, name, bases, attrs): + if cls == ModelFormMetaclass: + m = attrs.get('__metaclass__', None) + if m is None: + parents = [b for b in bases if issubclass(b, ModelForm)] + for c in parents: + if c.__metaclass__ != ModelFormMetaclass: + m = c.__metaclass__ + break + + if m is not None: + return m(name, bases, attrs) + + return _old(cls, name, bases, attrs) +ModelFormMetaclass.__new__ = staticmethod(_new) +# END HACK -_old_metaclass_new = ModelFormMetaclass.__new__ -def _new_metaclass_new(cls, name, bases, attrs): - formfield_callback = attrs.get('formfield_callback', lambda f, **kwargs: f.formfield(**kwargs)) - new_class = _old_metaclass_new(cls, name, bases, attrs) - opts = new_class._meta - if issubclass(new_class, EntityFormBase) and opts.model: - # "override" proxy fields with declared fields by excluding them if there's a name conflict. - exclude = (list(opts.exclude or []) + new_class.declared_fields.keys()) or None - proxy_fields = proxy_fields_for_entity_model(opts.model, opts.fields, exclude, opts.widgets, formfield_callback) # don't pass in formfield_callback +class EntityFormMetaclass(ModelFormMetaclass): + def __new__(cls, name, bases, attrs): + try: + parents = [b for b in bases if issubclass(b, EntityForm)] + except NameError: + # We are defining EntityForm itself + parents = None + sup = super(EntityFormMetaclass, cls) + + if not parents: + # Then there's no business trying to use proxy fields. + return sup.__new__(cls, name, bases, attrs) + + # Fake a declaration of all proxy fields so they'll be handled correctly. + opts = ModelFormOptions(attrs.get('Meta', None)) + + if opts.model: + formfield_callback = attrs.get('formfield_callback', None) + proxy_fields = proxy_fields_for_entity_model(opts.model, opts.fields, opts.exclude, opts.widgets, formfield_callback) + else: + proxy_fields = {} + + new_attrs = proxy_fields.copy() + new_attrs.update(attrs) + + new_class = sup.__new__(cls, name, bases, new_attrs) new_class.proxy_fields = proxy_fields - new_class.base_fields.update(proxy_fields) - return new_class + return new_class -ModelFormMetaclass.__new__ = staticmethod(_new_metaclass_new) -# END HACK - - -class EntityForm(EntityFormBase): # Would inherit from ModelForm directly if it weren't for the above HACK +class EntityForm(ModelForm): + __metaclass__ = EntityFormMetaclass + def __init__(self, *args, **kwargs): initial = kwargs.pop('initial', None) instance = kwargs.get('instance', None) diff --git a/middleware.py b/middleware.py index c0b1e9e..5ec3e77 100644 --- a/middleware.py +++ b/middleware.py @@ -24,16 +24,18 @@ class LazyNode(object): node, subpath = Node.objects.get_with_path(path, root=getattr(current_site, 'root_node', None), absolute_result=False) except Node.DoesNotExist: node = None - - if node: + else: if subpath is None: subpath = "" subpath = "/" + subpath - if trailing_slash and subpath[-1] != "/": - subpath += "/" - - node.subpath = subpath + if not node.handles_subpath(subpath): + node = None + else: + if trailing_slash and subpath[-1] != "/": + subpath += "/" + + node.subpath = subpath request._found_node = node @@ -46,7 +48,10 @@ class RequestNodeMiddleware(object): request.__class__.node = LazyNode() def process_view(self, request, view_func, view_args, view_kwargs): - request._cached_node_path = view_kwargs.get('path', '/') + try: + request._cached_node_path = view_kwargs['path'] + except KeyError: + pass def process_exception(self, request, exception): if settings.DEBUG or not hasattr(request, 'node') or not request.node: diff --git a/models/base.py b/models/base.py index faac89b..af1e880 100644 --- a/models/base.py +++ b/models/base.py @@ -271,9 +271,9 @@ class EntityOptions(object): class EntityBase(models.base.ModelBase): def __new__(cls, name, bases, attrs): + entity_meta = attrs.pop('EntityMeta', None) new = super(EntityBase, cls).__new__(cls, name, bases, attrs) - entity_options = attrs.pop('EntityMeta', None) - setattr(new, '_entity_meta', EntityOptions(entity_options)) + new.add_to_class('_entity_meta', EntityOptions(entity_meta)) entity_class_prepared.send(sender=new) return new diff --git a/models/fields/__init__.py b/models/fields/__init__.py index 25af832..1f9603e 100644 --- a/models/fields/__init__.py +++ b/models/fields/__init__.py @@ -51,8 +51,16 @@ class JSONField(models.TextField): models.signals.pre_init.connect(self.fix_init_kwarg, sender=cls) def fix_init_kwarg(self, sender, args, kwargs, **signal_kwargs): + # Anything passed in as self.name is assumed to come from a serializer and + # will be treated as a json string. if self.name in kwargs: - kwargs[self.attname] = json.dumps(kwargs.pop(self.name)) + value = kwargs.pop(self.name) + + # Hack to handle the xml serializer's handling of "null" + if value is None: + value = 'null' + + kwargs[self.attname] = value def formfield(self, *args, **kwargs): kwargs["form_class"] = JSONFormField diff --git a/models/pages.py b/models/pages.py index 39125ef..86db88f 100644 --- a/models/pages.py +++ b/models/pages.py @@ -18,16 +18,24 @@ from philo.signals import page_about_to_render_to_string, page_finished_renderin class LazyContainerFinder(object): - def __init__(self, nodes): + def __init__(self, nodes, extends=False): self.nodes = nodes self.initialized = False self.contentlet_specs = set() self.contentreference_specs = SortedDict() self.blocks = {} self.block_super = False + self.extends = extends def process(self, nodelist): for node in nodelist: + if self.extends: + if isinstance(node, BlockNode): + self.blocks[node.name] = block = LazyContainerFinder(node.nodelist) + block.initialize() + self.blocks.update(block.blocks) + continue + if isinstance(node, ContainerNode): if not node.references: self.contentlet_specs.add(node.name) @@ -36,15 +44,6 @@ class LazyContainerFinder(object): self.contentreference_specs[node.name] = node.references continue - if isinstance(node, BlockNode): - self.blocks[node.name] = block = LazyContainerFinder(node.nodelist) - block.initialize() - self.blocks.update(block.blocks) - continue - - if isinstance(node, ExtendsNode): - continue - if isinstance(node, VariableNode): if node.filter_expression.var.lookups == (u'block', u'super'): self.block_super = True @@ -97,7 +96,7 @@ class Template(TreeModel): if extends: if extends.nodelist: - nodelists.append(LazyContainerFinder(extends.nodelist)) + nodelists.append(LazyContainerFinder(extends.nodelist, extends=True)) loaded_template = getattr(extends, LOADED_TEMPLATE_ATTR) nodelists.extend(build_extension_tree(loaded_template.nodelist)) else: @@ -131,7 +130,7 @@ class Template(TreeModel): return contentlet_specs, contentreference_specs def __unicode__(self): - return self.get_path(pathsep=u' › ', field='name') + return self.name class Meta: app_label = 'philo' diff --git a/urls.py b/urls.py index 47be7da..0363224 100644 --- a/urls.py +++ b/urls.py @@ -3,6 +3,6 @@ from philo.views import node_view urlpatterns = patterns('', - url(r'^$', node_view, name='philo-root'), + url(r'^$', node_view, kwargs={'path': '/'}, name='philo-root'), url(r'^(?P.*)$', node_view, name='philo-node-by-path') ) diff --git a/validators.py b/validators.py index 8b39abd..5ae9409 100644 --- a/validators.py +++ b/validators.py @@ -3,6 +3,7 @@ from django.core.validators import RegexValidator from django.core.exceptions import ValidationError from django.template import Template, Parser, Lexer, TOKEN_BLOCK, TOKEN_VAR, TemplateSyntaxError from django.utils import simplejson as json +from django.utils.html import escape, mark_safe import re from philo.utils import LOADED_TEMPLATE_ATTR @@ -116,6 +117,16 @@ class TemplateValidationParser(Parser): raise ValidationError('Tag "%s" is not permitted here.' % command) +def linebreak_iter(template_source): + # Cribbed from django/views/debug.py + yield 0 + p = template_source.find('\n') + while p >= 0: + yield p+1 + p = template_source.find('\n', p+1) + yield len(template_source) + 1 + + class TemplateValidator(object): def __init__(self, allow=None, disallow=None, secure=True): self.allow = allow @@ -128,6 +139,14 @@ class TemplateValidator(object): except ValidationError: raise except Exception, e: + if hasattr(e, 'source') and isinstance(e, TemplateSyntaxError): + origin, (start, end) = e.source + template_source = origin.reload() + upto = 0 + for num, next in enumerate(linebreak_iter(template_source)): + if start >= upto and end <= next: + raise ValidationError(mark_safe("Template code invalid: \"%s\" (%s:%d).
%s" % (escape(template_source[start:end]), origin.loadname, num, e))) + upto = next raise ValidationError("Template code invalid. Error was: %s: %s" % (e.__class__.__name__, e)) def validate_template(self, template_string): diff --git a/views.py b/views.py index f5a2c7f..598be36 100644 --- a/views.py +++ b/views.py @@ -28,7 +28,7 @@ def node_view(request, path=None, **kwargs): subpath = request.node.subpath # Explicitly disallow trailing slashes if we are otherwise at a node's url. - if request.path and request.path != "/" and request.path[-1] == "/" and subpath == "/": + if request._cached_node_path != "/" and request._cached_node_path[-1] == "/" and subpath == "/": return HttpResponseRedirect(node.get_absolute_url()) if not node.handles_subpath(subpath):