Commits

Horst Gutmann committed f4d5486

Adds support for global sessions

  • Participants
  • Parent commits 50e5f57

Comments (0)

Files changed (7)

pyconde/conf/global_settings.py

 QUEUE_EMAIL_BOX_SSL = None
 QUEUE_EMAIL_BOX_PASSWORD = None
 
+SCHEDULE_CACHE_SCHEDULE = True

pyconde/schedule/migrations/0007_auto__add_field_session_is_global.py

+# 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 'Session.is_global'
+        db.add_column('schedule_session', 'is_global', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Session.is_global'
+        db.delete_column('schedule_session', 'is_global')
+
+
+    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': {'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'}),
+            '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'}),
+            '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'}),
+            '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'})
+        },
+        'cms.cmsplugin': {
+            'Meta': {'object_name': 'CMSPlugin'},
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': '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', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
+            'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
+            'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+            'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
+        },
+        'cms.placeholder': {
+            'Meta': {'object_name': 'Placeholder'},
+            'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'conference.audiencelevel': {
+            'Meta': {'object_name': 'AudienceLevel'},
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'conference.conference': {
+            'Meta': {'object_name': 'Conference'},
+            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'reviews_active': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+            'reviews_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'reviews_start_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'timezone': ('timezones.fields.TimeZoneField', [], {'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'conference.location': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Location'},
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+            'used_for_sessions': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+        },
+        'conference.section': {
+            'Meta': {'object_name': 'Section'},
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+            'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'})
+        },
+        'conference.sessionduration': {
+            'Meta': {'object_name': 'SessionDuration'},
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'minutes': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'conference.sessionkind': {
+            'Meta': {'object_name': 'SessionKind'},
+            'closed': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}),
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+            'start_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+        },
+        'conference.track': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Track'},
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'}),
+            'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+        },
+        'contenttypes.contenttype': {
+            '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'})
+        },
+        'proposals.proposal': {
+            'Meta': {'object_name': 'Proposal'},
+            'abstract': ('django.db.models.fields.TextField', [], {}),
+            'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'proposal_participations'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['speakers.Speaker']"}),
+            'audience_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.AudienceLevel']"}),
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'description': ('django.db.models.fields.TextField', [], {'max_length': '400'}),
+            'duration': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.SessionDuration']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.SessionKind']"}),
+            'modified_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposals'", 'to': "orm['speakers.Speaker']"}),
+            'submission_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'track': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Track']", 'null': 'True', 'blank': 'True'})
+        },
+        'schedule.completescheduleplugin': {
+            'Meta': {'object_name': 'CompleteSchedulePlugin', 'db_table': "'cmsplugin_completescheduleplugin'", '_ormbases': ['cms.CMSPlugin']},
+            'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
+            'sections': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['conference.Section']", 'null': 'True', 'blank': 'True'})
+        },
+        'schedule.session': {
+            'Meta': {'object_name': 'Session'},
+            'abstract': ('django.db.models.fields.TextField', [], {}),
+            'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'session_participations'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['speakers.Speaker']"}),
+            'audience_level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.AudienceLevel']"}),
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'description': ('django.db.models.fields.TextField', [], {'max_length': '400'}),
+            'duration': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.SessionDuration']"}),
+            'end': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_global': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.SessionKind']"}),
+            'location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Location']", 'null': 'True', 'blank': 'True'}),
+            'modified_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'proposal': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'session'", 'null': 'True', 'to': "orm['proposals.Proposal']"}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'sessions'", 'null': 'True', 'to': "orm['conference.Section']"}),
+            'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sessions'", 'to': "orm['speakers.Speaker']"}),
+            'start': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'submission_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'track': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Track']", 'null': 'True', 'blank': 'True'})
+        },
+        'schedule.sideevent': {
+            'Meta': {'object_name': 'SideEvent'},
+            'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Conference']"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'end': ('django.db.models.fields.DateTimeField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_global': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_pause': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'location': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['conference.Location']", 'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'side_events'", 'null': 'True', 'to': "orm['conference.Section']"}),
+            'start': ('django.db.models.fields.DateTimeField', [], {})
+        },
+        'speakers.speaker': {
+            'Meta': {'object_name': 'Speaker'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'speaker_profile'", 'unique': 'True', 'to': "orm['auth.User']"})
+        },
+        'taggit.tag': {
+            'Meta': {'object_name': 'Tag'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
+        },
+        'taggit.taggeditem': {
+            'Meta': {'object_name': 'TaggedItem'},
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
+        }
+    }
+
+    complete_apps = ['schedule']

pyconde/schedule/models.py

         verbose_name=_("proposal"))
     location = models.ForeignKey(conference_models.Location,
         verbose_name=_("location"), blank=True, null=True)
+    is_global = models.BooleanField(_("is global"), default=False)
 
     @classmethod
     def create_from_proposal(cls, proposal):

pyconde/schedule/templatetags/schedule_tags.py

 import logging
 
-from django.template import Library, Node
+from django.template import Library, Node, TemplateSyntaxError
 
 from .. import utils
 from .. import models
         raise TemplateSyntaxError("You have to specify at least one event")
     nodelist = parser.parse(('endpreloadevents',))
     parser.delete_first_token()
-    return PreloadEventsNode(nodelist, event_names=event_names)
+    return PreloadEventsNode(nodelist, event_names=event_names)

pyconde/schedule/utils.py

 import datetime
 import collections
 from  django.utils.datastructures import SortedDict
+from django.conf import settings
 
 from pyconde.conference import models as conference_models
 
     return data
 
 
-def create_schedule(row_duration=30, uncached=False):
+def create_schedule(row_duration=30, uncached=None):
     """
     Creates a schedule for each section of the conference.
 
     @param row_duration duration represented by a row in minutes
     """
+    if uncached is None:
+        uncached = not getattr(settings, 'SCHEDULE_CACHE_SCHEDULE', True)
     conf = conference_models.current_conference()
     cache_key = 'schedule:{0}:{1}'.format(conf.pk, row_duration)
     if not uncached:
     result = SortedDict()
     for section in conference_models.Section.objects.order_by('order', 'start_date').all():
         section_schedule = create_section_schedule(section,
-            row_duration=row_duration)
+            row_duration=row_duration, uncached=uncached)
         result[section] = section_schedule
     if not uncached:
         cache.set(cache_key, result, 180)
             return section_schedule
 
     sessions = list(section.sessions
-        .select_related('location', 'audience_level', 'speaker', 'track')
+        .select_related('location', 'audience_level', 'speaker', 'track', 'kind')
         .order_by('start')
         .all())
     side_events = list(section.side_events\
 
     locations = set()
     for session in sessions:
+        if session.is_global:
+            continue
         locations.add(session.location)
     for evt in side_events:
         # Global events span all session locations and therefor the location
         self.level_name = None
         self.location = event.location if event else None
         self.event = None
+        self.type = None
+        self.session_kind = None
         if event is not None:
             self.event = event
             self.type = event.__class__.__name__.lower()
             self.end = event.end
             if isinstance(event, models.Session):
                 self.name = event.title
+                self.type = 'session'
+                self.session_kind = self.event.kind.slug if self.event.kind else None
+                self.is_global = event.is_global
                 if event.speaker:
                     self.speakers.append(unicode(event.speaker))
                 for speaker in event.additional_speakers.select_related('user').all():
                 if event.audience_level:
                     self.level_name = event.audience_level.name
             else:
+                self.type = 'sideevent'
                 self.is_global = event.is_global
                 self.is_pause = event.is_pause
                 self.name = event.name

pyconde/templates/schedule/plugins/complete.html

                     <td>&nbsp;</td>
                 {% else %}
                     {% if evt.is_global %}
-                    <td class="filled global" rowspan="{{ evt.rowspan }}" colspan="{{ grid.0|length }}"><a href="{{ evt.url }}">{{ evt.event }}</a></td>
+                    <td class="filled {% if evt.type == 'sideevent' %}global{% endif %}" rowspan="{{ evt.rowspan }}" colspan="{{ grid.0|length }}">{% eventinfo evt %}</td>
                     {% else %}
                     <td class="filled" rowspan="{{ evt.rowspan }}">
-                        <a href="{{ evt.url }}">{{ evt.name }}</a><br />
-                        {% if evt.speakers %}von {{ evt.speakers|join:', ' }}{% endif %}
-                        {% if evt.level_name %}für {{ evt.level_name }}{% endif %}
+                        {% eventinfo evt %}
                     </td>
                     {% endif %}
                 {% endif %}
 </table>
 {% endfor %}{# day #}
 {% endfor %}{# section #}
-</div>
+</div>

pyconde/templates/schedule/tags/event.html

-<a href="{{ event.url }}">{{ event.name }}</a>
+<a href="{{ event.url }}">{% if event.session_kind == 'keynote'%}KEYNOTE: {% endif %}{{ event.name }}</a>
+{% if event.type == 'session' %}
+<br />
+{% if event.speakers %}von {{ event.speakers|join:', ' }}{% endif %}
+{% if event.level_name %}für {{ event.level_name }}{% endif %}
+{% endif %}