Merge lp:~cjohnston/summit/new-meeting-stuff into lp:summit

Proposed by Chris Johnston
Status: Merged
Merged at revision: 313
Proposed branch: lp:~cjohnston/summit/new-meeting-stuff
Merge into: lp:summit
Prerequisite: lp:~svwilliams/summit/left-bar-navpanel
Diff against target: 1495 lines (+869/-149)
28 files modified
.bzrignore (+2/-0)
summit/common/templates/base.html (+8/-31)
summit/common/templates/common/index.html (+5/-2)
summit/django.wsgi (+2/-3)
summit/schedule/admin/meetingadmin.py (+1/-1)
summit/schedule/autoslug.py (+79/-0)
summit/schedule/forms.py (+82/-4)
summit/schedule/migrations/0017_add_review_status.py (+204/-0)
summit/schedule/models/meetingmodel.py (+15/-1)
summit/schedule/templates/schedule/create_private.html (+1/-1)
summit/schedule/templates/schedule/daily.html (+7/-6)
summit/schedule/templates/schedule/edit_meeting.html (+45/-0)
summit/schedule/templates/schedule/edit_private.html (+1/-1)
summit/schedule/templates/schedule/meeting.html (+26/-15)
summit/schedule/templates/schedule/meeting_review.html (+45/-0)
summit/schedule/templates/schedule/mobile.html (+4/-1)
summit/schedule/templates/schedule/nosession.html (+1/-0)
summit/schedule/templates/schedule/not-attending.html (+1/-0)
summit/schedule/templates/schedule/past_summit.html (+9/-7)
summit/schedule/templates/schedule/propose_meeting.html (+45/-0)
summit/schedule/templates/schedule/review.html (+115/-0)
summit/schedule/templates/schedule/schedule.html (+5/-5)
summit/schedule/templates/schedule/summit.html (+44/-37)
summit/schedule/templates/schedule/summit_info.html (+1/-1)
summit/schedule/templates/schedule/tracks.html (+25/-28)
summit/schedule/views.py (+90/-4)
summit/ubuntu_settings.py (+2/-1)
summit/urls.py (+4/-0)
To merge this branch: bzr merge lp:~cjohnston/summit/new-meeting-stuff
Reviewer Review Type Date Requested Status
Summit Hackers Pending
Review via email: mp+96157@code.launchpad.net

This proposal supersedes a proposal from 2012-03-01.

To post a comment you must log in.
303. By Chris Johnston

Fix conflict from production

304. By Chris Johnston

[r=mhall119] Adds django sites to summit to allow for multiple different unique sites

305. By Chris Johnston

Version 1.0.6 Release

306. By Chris Johnston

[r=mhall119] Reverses the order of the past summits so that newest appears first.

307. By Chris Johnston

[r=mhall119] This adds theme support to Summit to allow LC and UDS to have separate themes, as well as add a menu app that will allow each site to have it's own menu without having to mess with templates.

308. By Chris Johnston

Version 1.0.7 release

309. By Chris Johnston

[r=mhall119] Fixes errors created in a previous merge that I failed to catch before pushing.

310. By Chris Johnston

Updating docs to reflect sites

311. By Chris Johnston

Fixes most theme issues

312. By Chris Johnston

Resolve conflicts

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-11-30 17:46:39 +0000
3+++ .bzrignore 2012-03-17 19:42:19 +0000
4@@ -10,3 +10,5 @@
5 www
6 README
7 env
8+ubuntu_settings.py
9+django.wsgi
10
11=== modified file 'summit/common/templates/base.html'
12--- summit/common/templates/base.html 2012-03-17 19:42:19 +0000
13+++ summit/common/templates/base.html 2012-03-17 19:42:19 +0000
14@@ -21,7 +21,7 @@
15 <link rel="stylesheet" type="text/css" media="screen" href="/media/css/layout.css" />
16 <link rel="stylesheet" type="text/css" media="screen" href="/media/css/style.css" />
17 <link rel="stylesheet" type="text/css" media="screen" href="/media/css/twidenash.css" />
18- {% block 960css %}<link rel="stylesheet" type="text/css" href="{{ubuntu_website_media}}/css/960.css" />{% endblock %}
19+ {% block 960css %}<!--<link rel="stylesheet" type="text/css" href="{{ubuntu_website_media}}/css/960.css" />-->{% endblock %}
20 {% block head %}
21 <script type="text/javascript">
22 var _gaq = _gaq || [];
23@@ -53,27 +53,13 @@
24 {% endif %}
25 {% endblock %}
26 {% block main_nav_links %}
27-<!--
28- <a class="main-nav-item" href="http://uds.ubuntu.com/travel/" title="Travel">Travel</a>
29- {% if next_summit %}
30- <a class="main-nav-item {% ifequal url_base next_summit.name %}current{% endifequal %}" href="{% url summit.schedule.views.summit next_summit.name %}" title="Schedule">Schedule</a>
31- {% else %}
32- <a class="main-nav-item {% ifequal url_base next_summit.name %}current{% endifequal %}" href="{% url summit.common.views.index %}" title="Schedule">Schedule</a>
33- {% endif %}
34- <a class="main-nav-item" href="http://uds.ubuntu.com/participate/" title="Participate">Participate</a>
35- <a class="main-nav-item" href="http://uds.ubuntu.com/social/" title="Social">Social</a>
36- <a class="main-nav-item" href="http://uds.ubuntu.com/uds-sponsors/" title=Sponsors">Sponsors</a>
37- <a class="main-nav-item" href="http://connect.linaro.org/events/event/linaro-connect-q112/" title="Linaro @ UDS">Linaro Connect</a>
38- {% if next_summit %}
39- <a class="main-nav-item {% ifequal url_base 'today' %}current{% endifequal %}" href="{% url summit.schedule.views.today_view next_summit.name %}" title="Today">Today</a>
40- {% endif %}
41-
42--->
43 {% load menubuilder %}
44 {% menu main_menu %}
45+ <ul class="clearfix">
46 {% for item in menuitems %}
47- <a class="main-nav-item" href="{{ item.url }}" title="{{ item.title|escape }}"{% if item.current %} class='current'{% endif %}>{{ item.title }}</a>
48+ <li{% if item.current %} class='active'{% endif %}><a class="main-nav-item" href="{{ item.url }}" title="{{ item.title|escape }}">{{ item.title }}</a></li>
49 {% endfor %}
50+ </ul>
51 {% endblock %}
52
53 {% block search %}{% endblock %}
54@@ -89,16 +75,7 @@
55 {% endfor %}
56 {% endif %}
57 {% endblock %}
58-{% block side_bar %}
59- <div id="side_bar">
60- <div id="side_bar_links_container">
61- <h3>Management Menu</h3>
62- {% block side_bar_links %}{% endblock %}
63- <!-- Concept 1: indented div <div style="padding: 2px 8px 0px 8px;font-size:medium"><a href="ubuntu.com">Create a Private Meeting</a></div> -->
64- <!-- Concept 2: list element <li><a href="ubuntu.com">Create a Private Meeting</a></li> -->
65- <li><a href="ubuntu.com">Create a Private Meeting</a></li>
66- </div>
67- </div>
68+{% block side_bar_links %}
69 {% endblock %}
70
71 {% block content %}
72@@ -109,9 +86,9 @@
73
74 {% block footer %}
75 <div class="copyright">
76- &copy; 2008-{% now "Y" %} Canonical Ltd., Ubuntu Community. Ubuntu is a registered trademark of Canonical Ltd.<br />
77- Problems with Summit? <a href="https://bugs.launchpad.net/summit/+filebug">File a Bug</a><br />
78- Summit {{ summit_version }}
79+ <p>&copy; 2008-{% now "Y" %} Canonical Ltd., Ubuntu Community. Ubuntu is a registered trademark of Canonical Ltd.</p>
80+ <p>Problems with Summit? <a href="https://bugs.launchpad.net/summit/+filebug">File a Bug &rsaquo;</a></p>
81+ <p>Summit {{ summit_version }}</p>
82 </div>
83 {% endblock %}
84
85
86=== modified file 'summit/common/templates/common/index.html'
87--- summit/common/templates/common/index.html 2012-01-28 11:37:36 +0000
88+++ summit/common/templates/common/index.html 2012-03-17 19:42:19 +0000
89@@ -24,10 +24,12 @@
90 {% endblock %}
91
92 {% block sub_nav %}{% endblock %}
93+{% block side_bar %}{% endblock %}
94 {% block content %}
95-<article class="minor-content">
96+<div class="row">
97+<article class="span-12">
98 {% if summit %}
99- <h1><a href="/{{ summit.name }}">{{ summit.title }}</a></h1>
100+ <h1><a href="/{{ summit.name }}">{{ summit.title }} &rsaquo;</a></h1>
101 <p>
102 {% include "schedule/summit_info.html" %}
103 </p>
104@@ -35,4 +37,5 @@
105 <p>No summits registered.</p>
106 {% endif %}
107 </article>
108+</div>
109 {% endblock %}
110
111=== modified file 'summit/django.wsgi'
112--- summit/django.wsgi 2012-03-06 22:20:05 +0000
113+++ summit/django.wsgi 2012-03-17 19:42:19 +0000
114@@ -1,9 +1,8 @@
115 import os
116 import sys
117
118-sys.path.insert(0,'/srv/django-1.3')
119-sys.path.append('/srv/summit.ubuntu.com')
120-sys.path.append('/srv/summit.ubuntu.com/summit')
121+sys.path.append('/srv/summit')
122+sys.path.append('/srv/summit/summit')
123 os.environ['DJANGO_SETTINGS_MODULE'] = 'ubuntu_settings'
124
125 import django.core.handlers.wsgi
126
127=== modified file 'summit/schedule/admin/meetingadmin.py'
128--- summit/schedule/admin/meetingadmin.py 2012-02-06 04:57:02 +0000
129+++ summit/schedule/admin/meetingadmin.py 2012-03-17 19:42:19 +0000
130@@ -140,7 +140,7 @@
131
132 fieldsets = (
133 (None, {
134- 'fields': ('summit', 'name', 'title', 'description',
135+ 'fields': ('summit', 'name', 'title', 'description', 'approved',
136 'type', 'tracks', 'topics', 'requires_dial_in', 'video'),
137 }),
138 ("References", {
139
140=== added file 'summit/schedule/autoslug.py'
141--- summit/schedule/autoslug.py 1970-01-01 00:00:00 +0000
142+++ summit/schedule/autoslug.py 2012-03-17 19:42:19 +0000
143@@ -0,0 +1,79 @@
144+from django.template.defaultfilters import slugify
145+
146+class AutoSlugMixin(object):
147+ """
148+ Automatically set slug to slugified version of the name if left empty.
149+ Use this as follows::
150+
151+ class MyModel(AutoSlugMixin, models.Model):
152+ def save(self):
153+ super(MyModel, self).save()
154+
155+ self.update_slug()
156+
157+ The name of the slug field and the field to populate from can be set
158+ using the `_slug_from` and `_slug_field` properties.
159+
160+ The big advantage of this method of setting slugs over others
161+ (ie. django-autoslug) is that we can set the value of slugs
162+ automatically based on the value of a field of an a field with a foreign
163+ key relation. For example::
164+
165+ class MyModel(AutoSlugMixin, models.Model):
166+ slug = models.SlugField()
167+
168+ def generate_slug(self):
169+ qs = self.mymodeltranslation_set.all()[:1]
170+ if qs.exists():
171+ return qs[0].name
172+ else:
173+ return ''
174+
175+ class MyModelTranslation(models.Model):
176+ parent = models.ForeignKey(MyModel)
177+ name = models.CharField()
178+
179+ def save(self):
180+ super(MyModel, self).save()
181+
182+ self.parent.update_slug()
183+
184+ (The code above is untested and _might_ be buggy.)
185+
186+ """
187+ _slug_from = 'title'
188+ _slug_field = 'name'
189+
190+ def slugify(self, name):
191+ return slugify(name)
192+
193+ def generate_slug(self):
194+ name = getattr(self, self._slug_from)
195+ return self.slugify(name)
196+
197+ def update_slug(self, commit=True):
198+ if not getattr(self, self._slug_field) and \
199+ getattr(self, self._slug_from):
200+ setattr(self, self._slug_field, self.generate_slug())
201+
202+ if commit:
203+ self.save()
204+
205+
206+class AutoUniqueSlugMixin(AutoSlugMixin):
207+ """ Make sure that the generated slug is unique. """
208+
209+ def is_unique_slug(self, slug):
210+ qs = self.__class__.objects.filter(**{self._slug_field: slug})
211+ return not qs.exists()
212+
213+ def generate_slug(self):
214+ original_slug = super(AutoUniqueSlugMixin, self).generate_slug()
215+ slug = original_slug
216+
217+ iteration = 1
218+ while not self.is_unique_slug(slug):
219+ slug = "%s-%d" % (original_slug, iteration)
220+ iteration += 1
221+
222+ return slug
223
224=== modified file 'summit/schedule/forms.py'
225--- summit/schedule/forms.py 2012-01-25 21:20:09 +0000
226+++ summit/schedule/forms.py 2012-03-17 19:42:19 +0000
227@@ -37,6 +37,67 @@
228 obj.user.first_name, obj.user.last_name, obj.user.username)
229
230
231+class MeetingFormBase(forms.ModelForm):
232+ participants = MultipleAttendeeField(
233+ queryset=Attendee.objects.all,
234+ widget=forms.CheckboxSelectMultiple,
235+ label='Participants',
236+ required=False)
237+
238+ class Media:
239+ css = {'all': (
240+ '/media/css/colortip-1.0-jquery.css',
241+ )}
242+ js = (
243+ '/media/js/colortip-1.0-jquery.js',
244+ )
245+
246+ def __init__(self, *args, **kwargs):
247+ if 'instance' in kwargs:
248+ if kwargs['instance'].pk is not None:
249+ # We get the 'initial' keyword argument or initialize it
250+ # as a dict if it didn't exist.
251+ initial = kwargs.setdefault('initial', {})
252+ # The widget for a ModelMultipleChoiceField expects
253+ # a list of primary key for the selected data.
254+ initial['participants'] = [
255+ attendee.pk
256+ for attendee in kwargs['instance'].participants.all()]
257+
258+ super(MeetingFormBase, self).__init__(*args, **kwargs)
259+
260+ summit = self.instance.summit
261+ self.fields['participants'].queryset = Attendee.objects.filter(
262+ summit=summit).order_by('user__first_name',
263+ 'user__last_name',
264+ 'user__username')
265+
266+ def save(self, commit=True):
267+ instance = super(MeetingFormBase, self).save(commit)
268+
269+ # Prepare a 'save_m2m' method for the form,
270+ if 'save_m2m' in dir(self):
271+ old_save_m2m = self.save_m2m
272+ else:
273+ old_save_m2m = None
274+ def save_m2m():
275+ if old_save_m2m is not None:
276+ old_save_m2m()
277+ # This is where we actually link the pizza with toppings
278+ instance.participants.clear()
279+ for participant in self.cleaned_data['participants']:
280+ record = Participant(meeting=instance, attendee=participant,
281+ required=True)
282+ record.save()
283+ self.save_m2m = save_m2m
284+
285+ # Do we need to save all changes now?
286+ if commit:
287+ instance.save()
288+ self.save_m2m()
289+
290+ return instance
291+
292 class PrivateMeetingFormBase(forms.ModelForm):
293 participants = MultipleAttendeeField(
294 queryset=Attendee.objects.all,
295@@ -98,16 +159,33 @@
296
297 return instance
298
299-
300 class CreatePrivateMeeting(PrivateMeetingFormBase, RenderableMixin):
301 class Meta:
302 model = Meeting
303- fields = ('name', 'title', 'description', 'spec_url', 'wiki_url',
304+ fields = ('title', 'description', 'tracks', 'spec_url', 'wiki_url',
305 'pad_url', 'requires_dial_in')
306
307
308 class EditPrivateMeeting(PrivateMeetingFormBase, RenderableMixin):
309 class Meta:
310 model = Meeting
311- fields = ('title', 'description', 'spec_url', 'wiki_url', 'pad_url',
312- 'requires_dial_in')
313+ fields = ('title', 'description', 'tracks', 'spec_url', 'wiki_url', 'pad_url',
314+ 'requires_dial_in')
315+
316+class ProposeMeeting(PrivateMeetingFormBase, RenderableMixin):
317+ class Meta:
318+ model = Meeting
319+ fields = ('title', 'description', 'tracks', 'spec_url', 'wiki_url',
320+ 'pad_url', 'requires_dial_in')
321+
322+
323+class EditMeeting(PrivateMeetingFormBase, RenderableMixin):
324+ class Meta:
325+ model = Meeting
326+ fields = ('title', 'description', 'tracks', 'spec_url', 'wiki_url', 'pad_url',
327+ 'requires_dial_in')
328+
329+class MeetingReview(forms.ModelForm, RenderableMixin):
330+ class Meta:
331+ model = Meeting
332+ fields = ('approved',)
333
334=== added file 'summit/schedule/migrations/0017_add_review_status.py'
335--- summit/schedule/migrations/0017_add_review_status.py 1970-01-01 00:00:00 +0000
336+++ summit/schedule/migrations/0017_add_review_status.py 2012-03-17 19:42:19 +0000
337@@ -0,0 +1,204 @@
338+# encoding: utf-8
339+import datetime
340+from south.db import db
341+from south.v2 import SchemaMigration
342+from django.db import models
343+
344+class Migration(SchemaMigration):
345+
346+ def forwards(self, orm):
347+
348+ # Adding field 'Meeting.approved'
349+ db.add_column('schedule_meeting', 'approved', self.gf('django.db.models.fields.CharField')(default='PENDING', max_length=10, null=True), keep_default=False)
350+
351+
352+ def backwards(self, orm):
353+
354+ # Deleting field 'Meeting.approved'
355+ db.delete_column('schedule_meeting', 'approved')
356+
357+
358+ models = {
359+ 'auth.group': {
360+ 'Meta': {'object_name': 'Group'},
361+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
362+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
363+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
364+ },
365+ 'auth.permission': {
366+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
367+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
368+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
369+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
370+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
371+ },
372+ 'auth.user': {
373+ 'Meta': {'ordering': "['username']", 'object_name': 'User'},
374+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
375+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
376+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
377+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
378+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
379+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
380+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
381+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
382+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
383+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
384+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
385+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
386+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
387+ },
388+ 'contenttypes.contenttype': {
389+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
390+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
391+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
392+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
393+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
394+ },
395+ 'schedule.agenda': {
396+ 'Meta': {'ordering': "('slot', 'room')", 'unique_together': "(('slot', 'room'),)", 'object_name': 'Agenda'},
397+ 'auto': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
398+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
399+ 'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Meeting']"}),
400+ 'room': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Room']"}),
401+ 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Slot']"})
402+ },
403+ 'schedule.attendee': {
404+ 'Meta': {'ordering': "('user__username', 'summit')", 'object_name': 'Attendee'},
405+ 'crew': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_column': "'crew'"}),
406+ 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}),
407+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
408+ 'secret_key_id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
409+ 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"}),
410+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
411+ 'topics': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Topic']", 'symmetrical': 'False', 'blank': 'True'}),
412+ 'tracks': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Track']", 'symmetrical': 'False', 'blank': 'True'}),
413+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
414+ },
415+ 'schedule.attendeebusy': {
416+ 'Meta': {'ordering': "('attendee', 'start_utc', 'end_utc')", 'object_name': 'AttendeeBusy'},
417+ 'attendee': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'busy_set'", 'to': "orm['schedule.Attendee']"}),
418+ 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}),
419+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
420+ 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"})
421+ },
422+ 'schedule.crew': {
423+ 'Meta': {'ordering': "('date_utc', 'attendee')", 'object_name': 'Crew'},
424+ 'attendee': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'crew_schedule'", 'to': "orm['schedule.Attendee']"}),
425+ 'date_utc': ('django.db.models.fields.DateField', [], {'db_column': "'date'"}),
426+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
427+ },
428+ 'schedule.lead': {
429+ 'Meta': {'ordering': "('summit', 'track')", 'object_name': 'Lead'},
430+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
431+ 'lead': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'lead'", 'to': "orm['schedule.Attendee']"}),
432+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
433+ 'track': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Track']"})
434+ },
435+ 'schedule.meeting': {
436+ 'Meta': {'object_name': 'Meeting'},
437+ 'approved': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '10', 'null': 'True'}),
438+ 'approver': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'approver_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}),
439+ 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assignee_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}),
440+ 'description': ('django.db.models.fields.TextField', [], {'max_length': '2047', 'blank': 'True'}),
441+ 'drafter': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'drafter_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}),
442+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
443+ 'name': ('summit.schedule.fields.NameField', [], {'max_length': '100'}),
444+ 'pad_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
445+ 'participants': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Attendee']", 'symmetrical': 'False', 'through': "orm['schedule.Participant']", 'blank': 'True'}),
446+ 'priority': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
447+ 'private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
448+ 'private_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}),
449+ 'requires_dial_in': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
450+ 'scribe': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'scribe_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}),
451+ 'slots': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
452+ 'spec_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
453+ 'status': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
454+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
455+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
456+ 'topics': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Topic']", 'symmetrical': 'False', 'blank': 'True'}),
457+ 'tracks': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Track']", 'symmetrical': 'False', 'blank': 'True'}),
458+ 'type': ('django.db.models.fields.CharField', [], {'default': "u'blueprint'", 'max_length': '15'}),
459+ 'video': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
460+ 'wiki_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
461+ },
462+ 'schedule.participant': {
463+ 'Meta': {'ordering': "('meeting', 'attendee', 'required')", 'object_name': 'Participant'},
464+ 'attendee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Attendee']"}),
465+ 'from_launchpad': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
466+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
467+ 'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Meeting']"}),
468+ 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
469+ },
470+ 'schedule.room': {
471+ 'Meta': {'ordering': "('summit', 'name')", 'object_name': 'Room'},
472+ 'end_utc': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_column': "'end'", 'blank': 'True'}),
473+ 'has_dial_in': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
474+ 'icecast_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
475+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
476+ 'name': ('summit.schedule.fields.NameField', [], {'max_length': '50'}),
477+ 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
478+ 'start_utc': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_column': "'start'", 'blank': 'True'}),
479+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
480+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
481+ 'tracks': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Track']", 'symmetrical': 'False', 'blank': 'True'}),
482+ 'type': ('django.db.models.fields.CharField', [], {'default': "u'open'", 'max_length': '7'})
483+ },
484+ 'schedule.roombusy': {
485+ 'Meta': {'ordering': "('room', 'start_utc', 'end_utc')", 'object_name': 'RoomBusy'},
486+ 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}),
487+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
488+ 'room': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'busy_set'", 'to': "orm['schedule.Room']"}),
489+ 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"})
490+ },
491+ 'schedule.slot': {
492+ 'Meta': {'ordering': "('summit', 'start_utc', 'end_utc')", 'object_name': 'Slot'},
493+ 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}),
494+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
495+ 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"}),
496+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
497+ 'type': ('django.db.models.fields.CharField', [], {'default': "u'open'", 'max_length': '7'})
498+ },
499+ 'schedule.summit': {
500+ 'Meta': {'ordering': "('name',)", 'object_name': 'Summit'},
501+ 'date_end': ('django.db.models.fields.DateField', [], {'null': 'True'}),
502+ 'date_start': ('django.db.models.fields.DateField', [], {'null': 'True'}),
503+ 'description': ('django.db.models.fields.TextField', [], {'max_length': '2047', 'blank': 'True'}),
504+ 'etherpad': ('django.db.models.fields.URLField', [], {'default': "'http://pad.ubuntu.com/'", 'max_length': '75'}),
505+ 'hashtag': ('django.db.models.fields.CharField', [], {'max_length': '25', 'blank': 'True'}),
506+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
507+ 'last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
508+ 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
509+ 'managers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'managers'", 'blank': 'True', 'to': "orm['auth.User']"}),
510+ 'name': ('summit.schedule.fields.NameField', [], {'max_length': '50'}),
511+ 'qr': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '100', 'blank': 'True'}),
512+ 'schedulers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'schedulers'", 'blank': 'True', 'to': "orm['auth.User']"}),
513+ 'state': ('django.db.models.fields.CharField', [], {'default': "u'sponsor'", 'max_length': '10'}),
514+ 'timezone': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
515+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
516+ },
517+ 'schedule.summitsprint': {
518+ 'Meta': {'ordering': "('summit', 'import_url')", 'object_name': 'SummitSprint'},
519+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
520+ 'import_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
521+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sprint_set'", 'to': "orm['schedule.Summit']"})
522+ },
523+ 'schedule.topic': {
524+ 'Meta': {'ordering': "('summit', 'title')", 'object_name': 'Topic'},
525+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
526+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
527+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
528+ },
529+ 'schedule.track': {
530+ 'Meta': {'ordering': "('summit', 'title', 'slug')", 'object_name': 'Track'},
531+ 'allow_adjacent_sessions': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
532+ 'color': ('django.db.models.fields.CharField', [], {'default': "'FFFFFF'", 'max_length': '6'}),
533+ 'description': ('django.db.models.fields.TextField', [], {'max_length': '1000', 'null': 'True'}),
534+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
535+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
536+ 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}),
537+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
538+ }
539+ }
540+
541+ complete_apps = ['schedule']
542
543=== modified file 'summit/schedule/models/meetingmodel.py'
544--- summit/schedule/models/meetingmodel.py 2012-01-27 12:35:43 +0000
545+++ summit/schedule/models/meetingmodel.py 2012-03-17 19:42:19 +0000
546@@ -32,12 +32,14 @@
547 from summit.schedule.models.topicmodel import Topic
548 from summit.schedule.models.attendeemodel import Attendee
549
550+from summit.schedule.autoslug import AutoSlugMixin
551+
552 __all__ = (
553 'Meeting',
554 )
555
556
557-class Meeting(models.Model):
558+class Meeting(AutoSlugMixin, models.Model):
559
560 class SchedulingError(Exception):
561 pass
562@@ -69,6 +71,12 @@
563 (90, u'Essential'),
564 )
565
566+ REVIEW_CHOICES = (
567+ (u'PENDING', u'Pending'),
568+ (u'APPROVED', u'Approved'),
569+ (u'DECLINED', u'Declined'),
570+ )
571+
572 summit = models.ForeignKey(Summit)
573 name = NameField(max_length=100, help_text="Lowercase alphanumeric characters and dashes only.")
574 title = models.CharField(max_length=100, help_text="Alphanumeric characters and spaces are allowed")
575@@ -90,6 +98,8 @@
576 pad_url = models.URLField(verify_exists=False,
577 verbose_name="Pad URL", null=True, blank=True)
578 slots = models.IntegerField(default=1)
579+ approved = models.CharField(max_length=10, choices=REVIEW_CHOICES,
580+ null=True, default='PENDING')
581 private = models.BooleanField(default=False)
582 private_key = models.CharField(max_length=32, null=True, blank=True)
583
584@@ -112,6 +122,10 @@
585 class Meta:
586 app_label = 'schedule'
587
588+ def save(self):
589+ super(Meeting, self).save()
590+ self.update_slug()
591+
592 def share(self):
593 if not self.pk or not self.private:
594 return
595
596=== modified file 'summit/schedule/templates/schedule/create_private.html'
597--- summit/schedule/templates/schedule/create_private.html 2012-01-25 22:42:54 +0000
598+++ summit/schedule/templates/schedule/create_private.html 2012-03-17 19:42:19 +0000
599@@ -25,7 +25,7 @@
600
601
602 {% block content %}
603-
604+{% block side_bar %}{% endblock %}
605 <article id="form" class="main-content">
606 {% if form.errors %}
607 <p style="color: red;">
608
609=== modified file 'summit/schedule/templates/schedule/daily.html'
610--- summit/schedule/templates/schedule/daily.html 2012-03-05 01:31:47 +0000
611+++ summit/schedule/templates/schedule/daily.html 2012-03-17 19:42:19 +0000
612@@ -158,14 +158,15 @@
613
614 {% block sub_nav_links %}
615 {% if ical %}
616-<a class="sub-nav-item" href="{{ ical }}">iCal Feed</a>
617+<li><a class="sub-nav-item" href="{{ ical }}">iCal Feed</a></li>
618 {% endif %}
619-<a class="sub-nav-item" href="{% url mobile %}">Mobile</a>
620-<a class="sub-nav-item" href="display">Wide Display</a>
621+<li><a class="sub-nav-item" href="{% url mobile %}">Mobile</a></li>
622+<li><a class="sub-nav-item" href="display">Wide Display</a></li>
623 {% endblock %}
624
625 {% block content %}
626-<article class="main-content">
627+<div class="row">
628+<article class="span-12">
629
630 <div class="schedule-head">
631 {% if summit.qr %}
632@@ -180,7 +181,7 @@
633 </div>
634
635 {% for slot, meetings in schedule.items %}
636-<table class="basic">
637+<table class="basic">
638 <thead><tr><th colspan="2">{{slot.start.time|strftime:"%H:%M"}} - {{slot.end.time|strftime:"%H:%M"}} {% ifequal slot.type 'plenary' %}[PLENARY]{% endifequal %}</th></tr></thead>
639 <tbody>
640 {% if slot.type == 'lunch' %}
641@@ -245,7 +246,7 @@
642 </table>
643 {% endfor %}
644
645-<br /><br /><br /><br />
646+</div>
647 </article>
648
649 <script>
650
651=== added file 'summit/schedule/templates/schedule/edit_meeting.html'
652--- summit/schedule/templates/schedule/edit_meeting.html 1970-01-01 00:00:00 +0000
653+++ summit/schedule/templates/schedule/edit_meeting.html 2012-03-17 19:42:19 +0000
654@@ -0,0 +1,45 @@
655+{% extends "base.html" %}
656+
657+{% block page_name %}Edit Meeting - {{ summit.title }}{%endblock %}
658+{% block sub_nav %}{% endblock %}
659+
660+{% block extrahead %}{{ block.super }}
661+ <script type="text/javascript" src="{{MEDIA_URL}}js/colortip-1.0-jquery.js"></script>
662+ <link rel="stylesheet" type="text/css" href="{{MEDIA_URL}}css/colortip-1.0-jquery.css"/>
663+{% endblock %}
664+
665+{% block extrafooter %}
666+<script type="text/javascript"><!--
667+$(document).ready(function(){
668+ $('span[rel*=help]').colorTip({color:'orange'});
669+});
670+--></script>
671+<style>
672+ul {
673+ height: 12em;
674+ overflow-y: scroll;
675+ overflow-x: hidden;
676+}
677+</style>
678+{% endblock %}
679+
680+
681+{% block content %}
682+{% block side_bar %}{% endblock %}
683+ <article id="form" class="main-content">
684+ {% if form.errors %}
685+ <p style="color: red;">
686+ Please correct the error{{ form.errors|pluralize }} below.
687+ </p>
688+ {% endif %}
689+
690+ <form action="{{ request.path_info }}" method="POST">
691+ <fieldset>
692+ <legend>Edit Meeting</legend>
693+ {{ form.as_template }}
694+ </fieldset>
695+ {% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %}
696+ <input type="submit" name="submit" value="Save" class="submit-button" />
697+ </form>
698+ </article>
699+{% endblock %}
700
701=== modified file 'summit/schedule/templates/schedule/edit_private.html'
702--- summit/schedule/templates/schedule/edit_private.html 2012-01-25 22:42:54 +0000
703+++ summit/schedule/templates/schedule/edit_private.html 2012-03-17 19:42:19 +0000
704@@ -25,7 +25,7 @@
705
706
707 {% block content %}
708-
709+{% block side_bar %}{% endblock %}
710 <article id="form" class="main-content">
711 {% if form.errors %}
712 <p style="color: red;">
713
714=== modified file 'summit/schedule/templates/schedule/meeting.html'
715--- summit/schedule/templates/schedule/meeting.html 2012-02-07 15:13:43 +0000
716+++ summit/schedule/templates/schedule/meeting.html 2012-03-17 19:42:19 +0000
717@@ -24,27 +24,32 @@
718 {% block sub_nav_links %}
719 {% if meeting.private %}
720 {% if meeting.private_key and meeting.private_key != '' %}
721- <a class="sub-nav-item" href="{% url summit.schedule.views.private_meeting meeting.summit.name, meeting.private_key, meeting.name|default:'-' %}">Shared URL</a>
722+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.private_meeting meeting.summit.name, meeting.private_key, meeting.name|default:'-' %}">Shared URL</a></li>
723 {% else %}
724- <a class="sub-nav-item" href="{% url summit.schedule.views.meeting meeting.summit.name, meeting.id, meeting.name|default:'-' %}+share">Share Meeting</a>
725+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.meeting meeting.summit.name, meeting.id, meeting.name|default:'-' %}+share">Share Meeting</a></li>
726 {% endif %}
727- <a class="sub-nav-item" href="{% url summit.schedule.views.edit_private summit.name, meeting.id, meeting.name|default:'-' %}">Edit Meeting</a>
728+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.edit_private summit.name, meeting.id, meeting.name|default:'-' %}">Edit Meeting</a></li>
729+ {% else %}
730+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.edit_meeting summit.name, meeting.id, meeting.name|default:'-' %}">Edit Meeting</a></li>
731 {% endif %}
732 {% if user_is_attending %}
733 {% if user_is_participating %}
734- <a class="sub-nav-item" href="{% url summit.schedule.views.unregister meeting.summit.name, meeting.id, meeting.name|default:'-' %}">Skip this meeting</a>
735+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.unregister meeting.summit.name, meeting.id, meeting.name|default:'-' %}">Skip this meeting</a></li>
736 {% endif %}
737 {% else %}
738 {% if meeting.spec_url %}
739- <a class="sub-nav-item" href="{{ meeting.spec_url }}/+subscribe">Subscribe to Blueprint</a>
740+ <li><a class="sub-nav-item" href="{{ meeting.spec_url }}/+subscribe">Subscribe to Blueprint</a></li>
741 {% endif %}
742- <a class="sub-nav-item" href="{% url summit.schedule.views.register meeting.summit.name, meeting.id, meeting.name|default:'-' %}">Attend this meeting</a>
743- {% endif %}
744- {% if meeting.spec_url %}<a class="sub-nav-item" href="{{ meeting.spec_url }}">Blueprint</a>{% endif %}
745+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.register meeting.summit.name, meeting.id, meeting.name|default:'-' %}">Attend this meeting</a></li>
746+ {% endif %}
747+ {% if meeting.spec_url %}
748+ <li><a class="sub-nav-item" href="{{ meeting.spec_url }}">Blueprint</a></li>
749+ {% endif %}
750 {% endblock %}
751
752 {% block content %}
753-<section class="double-side-content">
754+<div class="row">
755+<section class="span-9">
756 <h2>{{ meeting.title }}</h2>
757 {% for ai in agenda_items %}
758 <h3>{{ ai.slot }} in {{ ai.room.title }}</h3>
759@@ -54,9 +59,9 @@
760 </div>
761
762 </section>
763+<article class="span-3 last">
764 {% if meeting.private %}
765 {% else %}
766-<article class="side-content alone">
767 <div class="share">
768 <a href="http://www.reddit.com/submit" onclick="window.location = 'http://www.reddit.com/submit?url=' + encodeURIComponent(window.location); return false"> <img style="padding-bottom: 4px;"src="http://www.reddit.com/static/spreddit7.gif" alt="submit to reddit" border="0" /></a><br />
769 <div id="fb-root"></div>
770@@ -74,17 +79,22 @@
771 <script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
772 <script src="http://www.stumbleupon.com/hostedbadge.php?s=5"></script>
773 </div>
774+
775+{% endif %}
776 </article>
777-{% endif %}
778-
779+</div>
780+<div class="row">
781+<div class="span-12">
782 {% if meeting.private %}
783 <h3>WARNING: Contents of this pad may not be private, and may be searcheable by non-attendees!</h3>
784 {% endif %}
785
786 <iframe width=100% height=700 src="{{ meeting.link_to_pad }}"></iframe>
787-
788+</div>
789+</div>
790+<div class="row">
791 {% ifnotequal meeting.type 'plenary' %}
792- <div id="Attendees" style="float:left;width:60%;">
793+ <div id="Attendees" class="span-7">
794 <h3>Attendees</h3>
795 {% for participant in participants %}
796 <a href="http://launchpad.net/~{{ participant.attendee.user }}">{% if participant.required %}<strong>{% endif %}{{ participant.attendee.name }}{% if participant.required %}</strong>{% endif %}</a>{% if not forloop.last %}, {% endif %}
797@@ -92,7 +102,7 @@
798 </div>
799 {% endifnotequal %}
800
801- <div id="Links" style="float:left;width:40%;">
802+ <div id="Links" class="span-5 last">
803 <h3>Links</h3>
804 <ul>
805 <li><a href="{{meeting.link_to_pad}}" target="_new">Notes in a separate window</a></li>
806@@ -106,4 +116,5 @@
807 </div>
808
809 </article>
810+</div>
811 {% endblock %}
812
813=== added file 'summit/schedule/templates/schedule/meeting_review.html'
814--- summit/schedule/templates/schedule/meeting_review.html 1970-01-01 00:00:00 +0000
815+++ summit/schedule/templates/schedule/meeting_review.html 2012-03-17 19:42:19 +0000
816@@ -0,0 +1,45 @@
817+{% extends "base.html" %}
818+
819+{% block page_name %}Review Meeting - {{ summit.title }}{%endblock %}
820+{% block sub_nav %}{% endblock %}
821+
822+{% block extrahead %}{{ block.super }}
823+ <script type="text/javascript" src="{{MEDIA_URL}}js/colortip-1.0-jquery.js"></script>
824+ <link rel="stylesheet" type="text/css" href="{{MEDIA_URL}}css/colortip-1.0-jquery.css"/>
825+{% endblock %}
826+
827+{% block extrafooter %}
828+<script type="text/javascript"><!--
829+$(document).ready(function(){
830+ $('span[rel*=help]').colorTip({color:'orange'});
831+});
832+--></script>
833+<style>
834+ul {
835+ height: 12em;
836+ overflow-y: scroll;
837+ overflow-x: hidden;
838+}
839+</style>
840+{% endblock %}
841+
842+
843+{% block content %}
844+{% block side_bar %}{% endblock %}
845+ <article id="form" class="main-content">
846+ {% if form.errors %}
847+ <p style="color: red;">
848+ Please correct the error{{ form.errors|pluralize }} below.
849+ </p>
850+ {% endif %}
851+
852+ <form action="{{ request.path_info }}" method="POST">
853+ <fieldset>
854+ <legend>Review Meeting</legend>
855+ {{ form.as_template }}
856+ </fieldset>
857+ {% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %}
858+ <input type="submit" name="submit" value="Save" class="submit-button" />
859+ </form>
860+ </article>
861+{% endblock %}
862
863=== modified file 'summit/schedule/templates/schedule/mobile.html'
864--- summit/schedule/templates/schedule/mobile.html 2012-01-23 01:18:55 +0000
865+++ summit/schedule/templates/schedule/mobile.html 2012-03-17 19:42:19 +0000
866@@ -5,7 +5,9 @@
867 {% block sub_nav %}{% endblock %}
868
869 {% block content %}
870-<article class="minor-content">
871+
872+<div class="row">
873+<article class="span-12">
874 <h1>Mobile Schedule</h1>
875
876 <p>For those that have an Android or iPhone we have a new way to access the UDS schedule. We have arranged to have the UDS schedule available on the <a href="http://guidebookapp.com/getit?ref=email">Guidebook</a> software. </p>
877@@ -23,4 +25,5 @@
878
879 <p>* Use the UDS Wifi as International roaming data rates may apply if you don't.</p>
880 </article>
881+</div>
882 {% endblock %}
883
884=== modified file 'summit/schedule/templates/schedule/nosession.html'
885--- summit/schedule/templates/schedule/nosession.html 2011-02-15 03:12:18 +0000
886+++ summit/schedule/templates/schedule/nosession.html 2012-03-17 19:42:19 +0000
887@@ -14,5 +14,6 @@
888 {% endblock %}
889
890 {% block content %}
891+{% block side_bar %}{% endblock %}
892 There are no sessions scheduled for today.
893 {% endblock %}
894
895=== modified file 'summit/schedule/templates/schedule/not-attending.html'
896--- summit/schedule/templates/schedule/not-attending.html 2012-01-23 01:18:55 +0000
897+++ summit/schedule/templates/schedule/not-attending.html 2012-03-17 19:42:19 +0000
898@@ -3,6 +3,7 @@
899 {% block page_name %}{{ summit.title }}{% endblock %}
900
901 {% block content %}
902+{% block side_bar %}{% endblock %}
903 <h1>{{ summit.title }}</h1>
904 {% include "schedule/summit_info.html" %}
905
906
907=== modified file 'summit/schedule/templates/schedule/past_summit.html'
908--- summit/schedule/templates/schedule/past_summit.html 2012-01-27 14:36:25 +0000
909+++ summit/schedule/templates/schedule/past_summit.html 2012-03-17 19:42:19 +0000
910@@ -4,18 +4,20 @@
911 {% block page_name %}Previous Summits{%endblock %}
912
913 {% block sub_nav_links %}
914- <a class="sub-nav-item" href="{% url summit.schedule.views.summit next_summit.name %}">Current Summit</a>
915+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.summit next_summit.name %}">Current Summit</a></li>
916 {% endblock %}
917
918 {% block content %}
919
920-<article class="main-content">
921 {% for summit in past_summit reversed %}
922-<h1><a href="{% url summit.schedule.views.summit summit.name %} ">{{ summit.title }}</a></h1>
923-<p>
924-{% include "schedule/summit_info.html" %}
925-</p>
926+ <div class="row">
927+ <article class="span-12">
928+ <h1><a href="{% url summit.schedule.views.summit summit.name %} ">{{ summit.title }} &rsaquo;</a></h1>
929+ <p>
930+ {% include "schedule/summit_info.html" %}
931+ </p>
932+ </article>
933+ </div>
934 {% endfor %}
935-</article>
936
937 {% endblock %}
938
939=== added file 'summit/schedule/templates/schedule/propose_meeting.html'
940--- summit/schedule/templates/schedule/propose_meeting.html 1970-01-01 00:00:00 +0000
941+++ summit/schedule/templates/schedule/propose_meeting.html 2012-03-17 19:42:19 +0000
942@@ -0,0 +1,45 @@
943+{% extends "base.html" %}
944+
945+{% block page_name %}Propse a Meeting - {{ summit.title }}{%endblock %}
946+{% block sub_nav %}{% endblock %}
947+
948+{% block extrahead %}{{ block.super }}
949+ <script type="text/javascript" src="{{MEDIA_URL}}js/colortip-1.0-jquery.js"></script>
950+ <link rel="stylesheet" type="text/css" href="{{MEDIA_URL}}css/colortip-1.0-jquery.css"/>
951+{% endblock %}
952+
953+{% block extrafooter %}
954+<script type="text/javascript"><!--
955+$(document).ready(function(){
956+ $('span[rel*=help]').colorTip({color:'orange'});
957+});
958+--></script>
959+<style>
960+ul {
961+ height: 12em;
962+ overflow-y: scroll;
963+ overflow-x: hidden;
964+}
965+</style>
966+{% endblock %}
967+
968+
969+{% block content %}
970+{% block side_bar %}{% endblock %}
971+ <article id="form" class="main-content">
972+ {% if form.errors %}
973+ <p style="color: red;">
974+ Please correct the error{{ form.errors|pluralize }} below.
975+ </p>
976+ {% endif %}
977+
978+ <form action="{{ request.path_info }}" method="POST">
979+ <fieldset>
980+ <legend>Propose a Meeting</legend>
981+ {{ form.as_template }}
982+ </fieldset>
983+ {% if is_popup %}<input type="hidden" name="_popup" value="1">{% endif %}
984+ <input type="submit" name="submit" value="Create" class="submit-button" />
985+ </form>
986+ </article>
987+{% endblock %}
988
989=== added file 'summit/schedule/templates/schedule/review.html'
990--- summit/schedule/templates/schedule/review.html 1970-01-01 00:00:00 +0000
991+++ summit/schedule/templates/schedule/review.html 2012-03-17 19:42:19 +0000
992@@ -0,0 +1,115 @@
993+{% extends "base.html" %}
994+
995+{% block page_name %}
996+Review Proposed Meetings - {{ summit.title }}
997+{% endblock %}
998+
999+{% block head %}
1000+{% if linaro %}
1001+ <base target="_blank" />
1002+{% endif %}
1003+{{ block.super }}
1004+<script language="JavaScript">
1005+
1006+function show_agenda_details(agenda_id, index_id) {
1007+ var elem_id = 'agenda-'+agenda_id+'-'+index_id+'-details'
1008+ var details = document.getElementById(elem_id)
1009+ details.style.display='block';
1010+}
1011+
1012+function hide_agenda_details(agenda_id, index_id) {
1013+ var elem_id = 'agenda-'+agenda_id+'-'+index_id+'-details'
1014+ var details = document.getElementById(elem_id)
1015+ details.style.display='none';
1016+}
1017+
1018+</script>
1019+<style>
1020+TABLE img.icon {
1021+ vertical-align: bottom;
1022+ width: 16px;
1023+ height: 16px;
1024+}
1025+
1026+table.basic span.main-agenda-item-tracks {
1027+ font-size: 0.8em;
1028+}
1029+
1030+div.agenda-details {
1031+ display: none;
1032+ padding: 5px;
1033+ position: absolute;
1034+ margin-left: 20px;
1035+ font-size: 0.9em;
1036+ color: #FFFFFF;
1037+ background-color: #101010;
1038+ border: #000000 1px solid;
1039+ border-radius: 5px;
1040+ min-width: 200px;
1041+ max-width: 500px;
1042+ z-index: 100;
1043+}
1044+
1045+div.meeting-description {
1046+ white-space: pre-wrap;
1047+}
1048+
1049+div.agenda-details LI {
1050+ font-size: 1.0em;
1051+}
1052+
1053+div.schedule-head {
1054+ position: relative;
1055+ overflow: visible;
1056+ z-index: 10;
1057+}
1058+
1059+div.schedule-head .schedule-qrcode {
1060+ height: 63px;
1061+ vertical-align: top;
1062+ margin-left: -3px;
1063+ margin-top: -3px;
1064+}
1065+
1066+div.schedule-head .schedule-date {
1067+ font-weight: normal;
1068+ font-size: 36px;
1069+ margin-left: 5px;
1070+}
1071+
1072+div.schedule-head .schedule-crew, .last-updated {
1073+ font-size: 0.7pc;
1074+}
1075+
1076+</style>
1077+{% endblock %}
1078+
1079+{% block sub_nav %}
1080+{% endblock %}
1081+
1082+{% block content %}
1083+{% block side_bar %}{% endblock %}
1084+<article class="main-content">
1085+
1086+{% for track, meetings in schedule.items %}
1087+<div class="schedule-head">
1088+ {{ track.title }}
1089+</div>
1090+<table class="basic">
1091+{% for meeting in meetings %}
1092+<tr style="background-color: {{ meeting.track_color }}; {% if meeting.private %}border: 1px; border-style: solid; border-color: #FF0000;{% endif %}">
1093+<td width="75%">
1094+ <a href="{{ meeting.meeting_page_url }}" style="color: #000000;" class="main-agenda-item-name">
1095+ {{ meeting.title }}
1096+ </a>
1097+</td>
1098+<td width="25%">
1099+<a href="{% url summit.schedule.views.meeting_review summit.name meeting.id %}">Status: {{ meeting.get_approved_display }}</a>
1100+</td>
1101+</tr>
1102+{% endfor %}
1103+</table>
1104+{% endfor%}
1105+</article>
1106+
1107+{% endblock %}
1108
1109=== modified file 'summit/schedule/templates/schedule/schedule.html'
1110--- summit/schedule/templates/schedule/schedule.html 2012-03-07 14:11:34 +0000
1111+++ summit/schedule/templates/schedule/schedule.html 2012-03-17 19:42:19 +0000
1112@@ -43,20 +43,20 @@
1113
1114 {% block sub_nav_links %}
1115 {% if schedule.edit %}
1116- <a class="sub-nav-item" href="{{ request.url }}?">Read Only</a>
1117+ <li><a class="sub-nav-item" href="{{ request.url }}?">Read Only</a></li>
1118 {% else %}
1119 {% if can_change_agenda %}
1120- <a class="sub-nav-item" href="{{ request.url }}?edit">Edit</a>
1121+ <li><a class="sub-nav-item" href="{{ request.url }}?edit">Edit</a></li>
1122 {% endif %}
1123 {% endif %}
1124 {% if ical %}
1125-<a class="sub-nav-item" href="{{ ical }}">iCal Feed</a>
1126+<li><a class="sub-nav-item" href="{{ ical }}">iCal Feed</a></li>
1127 {% endif %}
1128-<a class="sub-nav-item" href="{% url mobile %}">Mobile</a>
1129+<li><a class="sub-nav-item" href="{% url mobile %}">Mobile</a></li>
1130 {% endblock %}
1131
1132 {% block content %}
1133-
1134+{% block side_bar %}{% endblock %}
1135 {% if schedule.date %}
1136 <div class="schedule-head">
1137 {% if summit.qr %}
1138
1139=== modified file 'summit/schedule/templates/schedule/summit.html'
1140--- summit/schedule/templates/schedule/summit.html 2012-03-07 14:11:34 +0000
1141+++ summit/schedule/templates/schedule/summit.html 2012-03-17 19:42:19 +0000
1142@@ -67,60 +67,39 @@
1143 {% block sub_nav_links %}
1144
1145 {% ifequal summit.state "sponsor" %}
1146- <a class="sub-nav-item" href="/{{ summit.name }}/sponsorship">Request Sponsorship</a>
1147+ <li><a class="sub-nav-item" href="/{{ summit.name }}/sponsorship">Request Sponsorship</a></li>
1148 {% if perms.sponsor.add_sponsorshipscore %}
1149- <a class="sub-nav-item" href="/{{ summit.name }}/suggestsponsorship">Suggest Sponsorship</a>
1150+ <li><a class="sub-nav-item" href="/{{ summit.name }}/suggestsponsorship">Suggest Sponsorship</a></li>
1151 {% endif %}
1152 {% endifequal %}
1153
1154 {% ifequal summit.state "review" %}
1155 {% if perms.sponsor.add_sponsorshipscore %}
1156- <a class="sub-nav-item" href="/{{ summit.name }}/sponsorship/review">Review Sponsorship Requests</a>
1157+ <li><a class="sub-nav-item" href="/{{ summit.name }}/sponsorship/review">Review Sponsorship Requests</a></li>
1158 {% endif %}
1159 {% endifequal %}
1160 {% if create_meeting %}
1161- <a class="sub-nav-item" href="/{{ summit.name }}/create_pm" title="Create Private Meeting">Create Private Meeting</a>
1162+ <li><a class="sub-nav-item" href="/{{ summit.name }}/create_pm" title="Create Private Meeting">Create Private Meeting</a></li>
1163 {% endif %}
1164- <a class="sub-nav-item" href="/{{ summit.name }}/tracks" title="Tracks">Tracks</a>
1165- <a class="sub-nav-item" href="/{{ summit.name }}.ical">All Sessions (iCal)</a>
1166+ <li><a class="sub-nav-item" href="/{{ summit.name }}/tracks" title="Tracks">Tracks</a></li>
1167+ <li><a class="sub-nav-item" href="/{{ summit.name }}.ical">All Sessions (iCal)</a></li>
1168 {% if attendee %}
1169- <a class="sub-nav-item" href="/{{ summit.name }}/participant/my_schedule_{{ attendee.secret_key }}.ical">My Sessions (iCal)</a>
1170+ <li><a class="sub-nav-item" href="/{{ summit.name }}/participant/my_schedule_{{ attendee.secret_key }}.ical">My Sessions (iCal)</a></li>
1171 {% endif %}
1172- <a class="sub-nav-item" href="{% url summit.schedule.views.past %}">Past Summits</a>
1173+ <li><a class="sub-nav-item" href="{% url summit.schedule.views.past %}">Past Summits</a></li>
1174 {% endblock %}
1175
1176 {% block content %}
1177
1178-<section class="double-side-content">
1179+<div class="row">
1180+<section class="span-9">
1181 <h1>{{ summit.title }}</h1>
1182 <p>
1183 {% include "schedule/summit_info.html" %}
1184 </p>
1185- {% if attendee %}
1186- <p>You are attending, you can update the days and times of your attendance in
1187- <a class="launchpad" href="http://launchpad.net/sprints/{{ summit.name }}/+attend"><img src="/media/img/gem-sm.png" /> Launchpad</a>.
1188- </p>
1189- <p>Download your
1190- <a href="/{{ summit.name }}/participant/my_schedule_{{ attendee.secret_key }}.ical">Participation Schedule</a> to import into your Calendar.
1191- </p>
1192- {% else %}
1193- {% if request.user.is_authenticated %}
1194- <p><strong>You are not registered as attending.</strong></p>
1195- <p>You can register your attendance in
1196- <a class="launchpad" href="http://launchpad.net/sprints/{{ summit.name }}/+attend"><img src="/media/img/gem-sm.png" /> Launchpad</a>.
1197- If you have recently done so, wait a few minutes and reload this page.
1198- </p>
1199- {% else %}
1200- <p><strong>You are not logged in.</strong></p>
1201- <p><a href="/openid/login?next={{login_next}}">Log in now</a></p>
1202- {% endif %}
1203- {% endif %}
1204- <p>
1205- {% include "schedule/schedule_list.html" %}
1206- </p>
1207 </section>
1208-<article class="side-content alone">
1209- <div class="share">
1210+<article class="span-3 last">
1211+ <div class="share alone">
1212 <a href="http://www.reddit.com/submit" onclick="window.location = 'http://www.reddit.com/submit?url=' + encodeURIComponent(window.location); return false"> <img style="padding-bottom: 4px;"src="http://www.reddit.com/static/spreddit7.gif" alt="submit to reddit" border="0" /></a><br />
1213 <div id="fb-root"></div>
1214 <script>(function(d, s, id) {
1215@@ -138,12 +117,40 @@
1216 <script src="http://www.stumbleupon.com/hostedbadge.php?s=5"></script>
1217 </div>
1218 </article>
1219+</div>
1220+<div class="row">
1221+<section class="span-8">
1222+ {% if attendee %}
1223+ <p>You are attending, you can update the days and times of your attendance <ins></ins>
1224+ <a class="launchpad" href="http://launchpad.net/sprints/{{ summit.name }}/+attend"><img src="/media/img/gem-sm.png" /> Launchpad</a>.
1225+ </p>
1226+ <p>Download your
1227+ <a href="/{{ summit.name }}/participant/my_schedule_{{ attendee.secret_key }}.ical">Participation Schedule</a> to import into your Calendar.
1228+ </p>
1229+ {% else %}
1230+ {% if request.user.is_authenticated %}
1231+ <p><strong>You are not registered as attending.</strong></p>
1232+ <p>You can register your attendance in
1233+ <a class="launchpad" href="http://launchpad.net/sprints/{{ summit.name }}/+attend"><img src="/media/img/gem-sm.png" /> Launchpad</a>.
1234+ If you have recently done so, wait a few minutes and reload this page.
1235+ </p>
1236+ {% else %}
1237+ <p><strong>You are not logged in.</strong></p>
1238+ <p><a href="/openid/login?next={{login_next}}">Log in now</a></p>
1239+ {% endif %}
1240+ {% endif %}
1241+ <p>
1242+ {% include "schedule/schedule_list.html" %}
1243+ </p>
1244+</section>
1245 {% if summit.hashtag %}
1246- <article class="side-content alone">
1247- <h3>Latest Tweets</h3>
1248- <h4>using {{ summit.hashtag }}</h4>
1249+ <article class="span-4 last">
1250+ <div class="share alone">
1251+ <h4>Latest Tweets</h4>
1252+ <h5>using {{ summit.hashtag }}</h5>
1253 <div class="twidenash" id="{{ summit.hashtag }}"></div>
1254+ </div>
1255 </article>
1256+</div>
1257 {% endif %}
1258-
1259 {% endblock %}
1260
1261=== modified file 'summit/schedule/templates/schedule/summit_info.html'
1262--- summit/schedule/templates/schedule/summit_info.html 2012-01-22 21:31:41 +0000
1263+++ summit/schedule/templates/schedule/summit_info.html 2012-03-17 19:42:19 +0000
1264@@ -6,4 +6,4 @@
1265 <strong>Ends:</strong> {{ summit.end|strftime:"%a, %d %b %Y %H:%M:%S %Z" }}</p>
1266 {% endif %}
1267 <p class="description">{{ summit.description|safe }}</p>
1268-<p><a class="launchpad" href="http://launchpad.net/sprints/{{ summit.name }}"><img src="/media/img/gem-sm.png" /> {{ summit.title }} in Launchpad</a></p>
1269+<p><a class="launchpad" href="http://launchpad.net/sprints/{{ summit.name }}"><img src="/media/img/gem-sm.png" /> {{ summit.title }} in Launchpad &rsaquo;</a></p>
1270
1271=== modified file 'summit/schedule/templates/schedule/tracks.html'
1272--- summit/schedule/templates/schedule/tracks.html 2012-01-25 18:43:02 +0000
1273+++ summit/schedule/templates/schedule/tracks.html 2012-03-17 19:42:19 +0000
1274@@ -4,37 +4,34 @@
1275 {% block sub_nav %}{% endblock %}
1276
1277 {% block content %}
1278-<article class="main-content">
1279+ <div class="row">
1280+ <div class="span-12">
1281+ <h1>{{ summit.title }} Tracks</h1>
1282+ </div>
1283+ </div>
1284 <h1>{{ summit.title }} Tracks</h1>
1285
1286 {% for track in summit.track_set.all %}
1287 {% if forloop.counter == 1 %}
1288- <div style="display:block;border-bottom-left-radius: 5px 5px;
1289- border-bottom-right-radius: 5px 5px;clear: both;
1290- padding: 5px;
1291- margin-bottom: -3px;">
1292- <ul class="tracks">
1293- {% endif %}
1294- <li>
1295- <h3><a href="/{{ summit.name }}/track/{{ track.slug|lower }}">{{ track.title }}</a></h3>
1296- <p>{{ track.description }}</p>
1297- {% if track.lead_set %}
1298- Lead: {% for lead in track.lead_set.all %}
1299- <a href="http://launchpad.net/~{{ lead.lead.user }}">{{ lead.lead.name }}</a>{% if not forloop.last %},{% endif %}
1300- {% endfor %}
1301- {% endif %}
1302- </li>
1303- {% if forloop.counter|divisibleby:"4" %}
1304- </ul>
1305- </div>
1306- <div style="display:block;border-bottom-left-radius: 5px 5px;
1307- border-bottom-right-radius: 5px 5px;clear: both;
1308- padding: 5px;
1309- margin-bottom: -3px;">
1310- <ul class="tracks">
1311- {% endif %}
1312+ <div class="row">
1313+ {% endif %}
1314+ {% if forloop.counter|divisibleby:"4" %}
1315+ <div class="span-3 last">
1316+ {% else %}
1317+ <div class="span-3">
1318+ {% endif %}
1319+
1320+ <h3><a href="/{{ summit.name }}/track/{{ track.slug|lower }}">{{ track.title }}</a></h3>
1321+ <p>{{ track.description }}</p>
1322+ {% if track.lead_set %}
1323+ Lead: {% for lead in track.lead_set.all %}
1324+ <a href="http://launchpad.net/~{{ lead.lead.user }}">{{ lead.lead.name }}</a>{% if not forloop.last %},{% endif %}{% endfor %}
1325+ {% endif %}
1326+ </div>
1327+
1328+ {% if forloop.counter|divisibleby:"4" %}
1329+ <div class="row">
1330+ {% endif %}
1331 {% endfor %}
1332- </ul>
1333- </div>
1334-</article>
1335+
1336 {% endblock %}
1337
1338=== modified file 'summit/schedule/views.py'
1339--- summit/schedule/views.py 2012-03-08 04:12:17 +0000
1340+++ summit/schedule/views.py 2012-03-17 19:42:19 +0000
1341@@ -35,7 +35,7 @@
1342
1343 from summit.schedule.render import schedule_factory, Schedule
1344
1345-from summit.schedule.forms import CreatePrivateMeeting, EditPrivateMeeting
1346+from summit.schedule.forms import *
1347
1348 __all__ = (
1349 'summit',
1350@@ -401,9 +401,9 @@
1351 if not summit.can_create_pm(attendee):
1352 return HttpResponseRedirect(reverse('summit.schedule.views.summit', args=(summit.name,)))
1353 else:
1354- meeting = Meeting(summit=summit, approver=attendee, private=True)
1355+ meeting = Meeting(summit=summit, approver=attendee, private=True, approved='APPROVED')
1356
1357- if request.method == 'POST':
1358+ if request.method == 'POST':
1359 form = CreatePrivateMeeting(data=request.POST, instance=meeting)
1360 if form.is_valid():
1361 form.save()
1362@@ -419,13 +419,33 @@
1363 context, RequestContext(request))
1364
1365 @summit_attendee_required
1366+def propose_meeting(request, summit, attendee):
1367+
1368+ meeting = Meeting(summit=summit, drafter=attendee, private=False, approved=False)
1369+
1370+ if request.method == 'POST':
1371+ form = ProposeMeeting(data=request.POST, instance=meeting)
1372+ if form.is_valid():
1373+ form.save()
1374+ return HttpResponseRedirect(meeting.meeting_page_url)
1375+ else:
1376+ form = ProposeMeeting(instance=meeting)
1377+
1378+ context = {
1379+ 'summit': summit,
1380+ 'form': form,
1381+ }
1382+ return render_to_response('schedule/propose_meeting.html',
1383+ context, RequestContext(request))
1384+
1385+@summit_attendee_required
1386 def edit_private(request, summit, attendee, meeting_id, meeting_slug):
1387 meeting = get_object_or_404(summit.meeting_set, id=meeting_id)
1388
1389 if attendee != meeting.approver:
1390 return HttpResponseRedirect(reverse('summit.schedule.views.summit', args=(summit.name,)))
1391 else:
1392- if request.method == 'POST':
1393+ if request.method == 'POST':
1394 form = EditPrivateMeeting(data=request.POST, instance=meeting)
1395 if form.is_valid():
1396 form.save()
1397@@ -439,3 +459,69 @@
1398 }
1399 return render_to_response('schedule/edit_private.html',
1400 context, RequestContext(request))
1401+
1402+@summit_attendee_required
1403+def edit_meeting(request, summit, attendee, meeting_id, meeting_slug):
1404+ meeting = get_object_or_404(summit.meeting_set, id=meeting_id)
1405+
1406+ if attendee != meeting.drafter:
1407+ return HttpResponseRedirect(reverse('summit.schedule.views.summit', args=(summit.name,)))
1408+ else:
1409+ if request.method == 'POST':
1410+ form = EditMeeting(data=request.POST, instance=meeting)
1411+ if form.is_valid():
1412+ form.save()
1413+ return HttpResponseRedirect(meeting.meeting_page_url)
1414+ else:
1415+ form = EditMeeting(instance=meeting)
1416+
1417+ context = {
1418+ 'summit': summit,
1419+ 'form': form,
1420+ }
1421+ return render_to_response('schedule/edit_meeting.html',
1422+ context, RequestContext(request))
1423+
1424+@summit_required
1425+def review_pending(request, summit, attendee):
1426+ if not Lead.objects.filter(lead=attendee).exists():
1427+ return HttpResponseRedirect(reverse('summit.schedule.views.summit', args=(summit.name,)))
1428+ else:
1429+ schedule = SortedDict()
1430+
1431+ for track in summit.track_set.all():
1432+ if not track in schedule:
1433+ schedule[track] = list()
1434+
1435+ # Add meetings from this slot
1436+ for meeting in track.meeting_set.exclude(approved='APPROVED'):
1437+ schedule[track].append(meeting)
1438+
1439+ context = {
1440+ 'summit': summit,
1441+ 'schedule': schedule,
1442+ }
1443+ return render_to_response("schedule/review.html", context,
1444+ context_instance=RequestContext(request))
1445+
1446+@summit_required
1447+def meeting_review(request, summit, attendee, meeting_id):
1448+ meeting = get_object_or_404(summit.meeting_set, id=meeting_id)
1449+
1450+ if not Lead.objects.filter(lead=attendee).exists():
1451+ return HttpResponseRedirect(reverse('summit.schedule.views.summit', args=(summit.name,)))
1452+ else:
1453+ if request.method == 'POST':
1454+ form = MeetingReview(data=request.POST, instance=meeting)
1455+ if form.is_valid():
1456+ form.save()
1457+ return HttpResponseRedirect(meeting.meeting_page_url)
1458+ else:
1459+ form = MeetingReview(instance=meeting)
1460+
1461+ context = {
1462+ 'summit': summit,
1463+ 'form': form,
1464+ }
1465+ return render_to_response('schedule/meeting_review.html',
1466+ context, RequestContext(request))
1467
1468=== modified file 'summit/ubuntu_settings.py'
1469--- summit/ubuntu_settings.py 2012-03-08 03:55:12 +0000
1470+++ summit/ubuntu_settings.py 2012-03-17 19:42:19 +0000
1471@@ -3,7 +3,8 @@
1472
1473 from settings import *
1474
1475-SITE_ROOT = 'http://summit.ubuntu.com'
1476+SITE_ROOT = 'http://summit.chrisjohnston.org'
1477+
1478
1479 SITE_ID = 1
1480
1481
1482=== modified file 'summit/urls.py'
1483--- summit/urls.py 2012-03-08 03:55:12 +0000
1484+++ summit/urls.py 2012-03-17 19:42:19 +0000
1485@@ -67,6 +67,10 @@
1486 url(r'^mobile/', 'mobile', name='mobile'),
1487 url(r'^logout$', 'logout_view', name='logout'),
1488 (r'^(?P<summit_name>[\w-]+)/$', 'summit'),
1489+ (r'^(?P<summit_name>[\w-]+)/propose_meeting/$', 'propose_meeting'),
1490+ (r'^(?P<summit_name>[\w-]+)/edit_meeting/(?P<meeting_id>\d+)/(?P<meeting_slug>[%+\.\w-]+)/$', 'edit_meeting'),
1491+ (r'^(?P<summit_name>[\w-]+)/review/$', 'review_pending'),
1492+ (r'^(?P<summit_name>[\w-]+)/review_meeting/(?P<meeting_id>\d+)/$', 'meeting_review'),
1493 (r'^(?P<summit_name>[\w-]+)/create_pm/$', 'create_private'),
1494 (r'^(?P<summit_name>[\w-]+)/edit_pm/(?P<meeting_id>\d+)/(?P<meeting_slug>[%+\.\w-]+)/$', 'edit_private'),
1495 (r'^(?P<summit_name>[\w-]+)/tracks$', 'tracks'),

Subscribers

People subscribed via source and target branches