Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Michael Hall | ||||
Approved revision: | 171 | ||||
Merged at revision: | 174 | ||||
Proposed branch: | lp:~james-w/summit/dial-in | ||||
Merge into: | lp:summit | ||||
Diff against target: |
309 lines (+242/-2) 6 files modified
summit/schedule/admin/meetingadmin.py (+1/-1) summit/schedule/admin/roomadmin.py (+1/-1) summit/schedule/migrations/0004_add_dial_in_fields.py (+193/-0) summit/schedule/models/meetingmodel.py (+5/-0) summit/schedule/models/roommodel.py (+4/-0) summit/schedule/tests.py (+38/-0) |
||||
To merge this branch: | bzr merge lp:~james-w/summit/dial-in | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Hall (community) | Approve | ||
Review via email: mp+75631@code.launchpad.net |
Commit message
Add fields on rooms and meetings for dial-in.
A meeting that requires dial-in can only be scheduled in to a room
that has it.
Description of the change
Hi,
This is a surprisingly small branch that adds dial-in knowledge
to meetings and rooms.
A meeting can specify that it requires dial-in, and such meetings
can only be scheduled in to rooms that have dial-in.
It will be up to admins to manage these fields, you can't put
something in the LP blueprint for instance.
My next branch will update the admin interface to show these
fields.
Thanks,
James
James Westby (james-w) wrote : | # |
- 171. By James Westby
-
Add the dial-in fields to the admin site.
James Westby (james-w) wrote : | # |
Hi,
Michael asked if we should be showing dial-in information on the schedule.
I talked to Joey about it, and he's not sure.
I propose that we land this so that the scheduling can be done, and we can
land something to store and display that information if it is needed, once
we know how it should work.
At worst the session lead could put the information in the etherpad for the
session.
Thanks,
James
Preview Diff
1 | === modified file 'summit/schedule/admin/meetingadmin.py' | |||
2 | --- summit/schedule/admin/meetingadmin.py 2011-05-31 10:43:35 +0000 | |||
3 | +++ summit/schedule/admin/meetingadmin.py 2011-09-15 20:51:24 +0000 | |||
4 | @@ -154,7 +154,7 @@ | |||
5 | 154 | fieldsets = ( | 154 | fieldsets = ( |
6 | 155 | (None, { | 155 | (None, { |
7 | 156 | 'fields': ('summit', 'name', 'title', 'description', | 156 | 'fields': ('summit', 'name', 'title', 'description', |
9 | 157 | 'type', 'tracks', 'topics'), | 157 | 'type', 'tracks', 'topics', 'requires_dial_in'), |
10 | 158 | }), | 158 | }), |
11 | 159 | ("References", { | 159 | ("References", { |
12 | 160 | 'fields': ('spec_url', 'wiki_url', 'pad_url'), | 160 | 'fields': ('spec_url', 'wiki_url', 'pad_url'), |
13 | 161 | 161 | ||
14 | === modified file 'summit/schedule/admin/roomadmin.py' | |||
15 | --- summit/schedule/admin/roomadmin.py 2010-03-05 10:33:36 +0000 | |||
16 | +++ summit/schedule/admin/roomadmin.py 2011-09-15 20:51:24 +0000 | |||
17 | @@ -36,7 +36,7 @@ | |||
18 | 36 | fieldsets = ( | 36 | fieldsets = ( |
19 | 37 | (None, { | 37 | (None, { |
20 | 38 | 'fields': ('summit', 'name', 'title', 'type', 'size', 'tracks', | 38 | 'fields': ('summit', 'name', 'title', 'type', 'size', 'tracks', |
22 | 39 | 'icecast_url'), | 39 | 'icecast_url', 'has_dial_in'), |
23 | 40 | }), | 40 | }), |
24 | 41 | ("Availability", { | 41 | ("Availability", { |
25 | 42 | 'fields': ('start_utc', 'end_utc'), | 42 | 'fields': ('start_utc', 'end_utc'), |
26 | 43 | 43 | ||
27 | === added file 'summit/schedule/migrations/0004_add_dial_in_fields.py' | |||
28 | --- summit/schedule/migrations/0004_add_dial_in_fields.py 1970-01-01 00:00:00 +0000 | |||
29 | +++ summit/schedule/migrations/0004_add_dial_in_fields.py 2011-09-15 20:51:24 +0000 | |||
30 | @@ -0,0 +1,193 @@ | |||
31 | 1 | # encoding: utf-8 | ||
32 | 2 | import datetime | ||
33 | 3 | from south.db import db | ||
34 | 4 | from south.v2 import SchemaMigration | ||
35 | 5 | from django.db import models | ||
36 | 6 | |||
37 | 7 | class Migration(SchemaMigration): | ||
38 | 8 | |||
39 | 9 | def forwards(self, orm): | ||
40 | 10 | |||
41 | 11 | # Adding field 'Meeting.requires_dial_in' | ||
42 | 12 | db.add_column('schedule_meeting', 'requires_dial_in', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False) | ||
43 | 13 | |||
44 | 14 | # Adding field 'Room.has_dial_in' | ||
45 | 15 | db.add_column('schedule_room', 'has_dial_in', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False) | ||
46 | 16 | |||
47 | 17 | |||
48 | 18 | def backwards(self, orm): | ||
49 | 19 | |||
50 | 20 | # Deleting field 'Meeting.requires_dial_in' | ||
51 | 21 | db.delete_column('schedule_meeting', 'requires_dial_in') | ||
52 | 22 | |||
53 | 23 | # Deleting field 'Room.has_dial_in' | ||
54 | 24 | db.delete_column('schedule_room', 'has_dial_in') | ||
55 | 25 | |||
56 | 26 | |||
57 | 27 | models = { | ||
58 | 28 | 'auth.group': { | ||
59 | 29 | 'Meta': {'object_name': 'Group'}, | ||
60 | 30 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
61 | 31 | 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), | ||
62 | 32 | 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) | ||
63 | 33 | }, | ||
64 | 34 | 'auth.permission': { | ||
65 | 35 | 'Meta': {'ordering': "('content_type__app_label', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, | ||
66 | 36 | 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
67 | 37 | 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), | ||
68 | 38 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
69 | 39 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) | ||
70 | 40 | }, | ||
71 | 41 | 'auth.user': { | ||
72 | 42 | 'Meta': {'object_name': 'User'}, | ||
73 | 43 | 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
74 | 44 | 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), | ||
75 | 45 | 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
76 | 46 | 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), | ||
77 | 47 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
78 | 48 | 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | ||
79 | 49 | 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
80 | 50 | 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
81 | 51 | 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||
82 | 52 | 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), | ||
83 | 53 | 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), | ||
84 | 54 | 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), | ||
85 | 55 | 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) | ||
86 | 56 | }, | ||
87 | 57 | 'contenttypes.contenttype': { | ||
88 | 58 | 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
89 | 59 | 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
90 | 60 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
91 | 61 | 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
92 | 62 | 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
93 | 63 | }, | ||
94 | 64 | 'schedule.agenda': { | ||
95 | 65 | 'Meta': {'ordering': "('slot', 'room')", 'unique_together': "(('slot', 'room'),)", 'object_name': 'Agenda'}, | ||
96 | 66 | 'auto': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
97 | 67 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
98 | 68 | 'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Meeting']"}), | ||
99 | 69 | 'room': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Room']"}), | ||
100 | 70 | 'slot': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Slot']"}) | ||
101 | 71 | }, | ||
102 | 72 | 'schedule.attendee': { | ||
103 | 73 | 'Meta': {'ordering': "('summit', 'user')", 'object_name': 'Attendee'}, | ||
104 | 74 | 'crew': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_column': "'crew'"}), | ||
105 | 75 | 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}), | ||
106 | 76 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
107 | 77 | 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"}), | ||
108 | 78 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}), | ||
109 | 79 | 'topics': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Topic']", 'symmetrical': 'False', 'blank': 'True'}), | ||
110 | 80 | 'tracks': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Track']", 'symmetrical': 'False', 'blank': 'True'}), | ||
111 | 81 | 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) | ||
112 | 82 | }, | ||
113 | 83 | 'schedule.attendeebusy': { | ||
114 | 84 | 'Meta': {'ordering': "('attendee', 'start_utc', 'end_utc')", 'object_name': 'AttendeeBusy'}, | ||
115 | 85 | 'attendee': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'busy_set'", 'to': "orm['schedule.Attendee']"}), | ||
116 | 86 | 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}), | ||
117 | 87 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
118 | 88 | 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"}) | ||
119 | 89 | }, | ||
120 | 90 | 'schedule.crew': { | ||
121 | 91 | 'Meta': {'ordering': "('date_utc', 'attendee')", 'object_name': 'Crew'}, | ||
122 | 92 | 'attendee': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'crew_schedule'", 'to': "orm['schedule.Attendee']"}), | ||
123 | 93 | 'date_utc': ('django.db.models.fields.DateField', [], {'db_column': "'date'"}), | ||
124 | 94 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) | ||
125 | 95 | }, | ||
126 | 96 | 'schedule.meeting': { | ||
127 | 97 | 'Meta': {'object_name': 'Meeting'}, | ||
128 | 98 | 'approver': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'approver_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}), | ||
129 | 99 | 'assignee': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'assignee_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}), | ||
130 | 100 | 'description': ('django.db.models.fields.TextField', [], {'max_length': '2047', 'blank': 'True'}), | ||
131 | 101 | 'drafter': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'drafter_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}), | ||
132 | 102 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
133 | 103 | 'name': ('summit.schedule.fields.NameField', [], {'max_length': '50', 'blank': 'True'}), | ||
134 | 104 | 'pad_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), | ||
135 | 105 | 'participants': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Attendee']", 'symmetrical': 'False', 'through': "'Participant'", 'blank': 'True'}), | ||
136 | 106 | 'priority': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | ||
137 | 107 | 'private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
138 | 108 | 'requires_dial_in': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
139 | 109 | 'scribe': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'scribe_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}), | ||
140 | 110 | 'slots': ('django.db.models.fields.IntegerField', [], {'default': '1'}), | ||
141 | 111 | 'spec_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), | ||
142 | 112 | 'status': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), | ||
143 | 113 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}), | ||
144 | 114 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
145 | 115 | 'topics': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Topic']", 'symmetrical': 'False', 'blank': 'True'}), | ||
146 | 116 | 'tracks': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Track']", 'symmetrical': 'False', 'blank': 'True'}), | ||
147 | 117 | 'type': ('django.db.models.fields.CharField', [], {'default': "u'blueprint'", 'max_length': '15'}), | ||
148 | 118 | 'videographer1': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'videographer1_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}), | ||
149 | 119 | 'videographer2': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'videographer2_set'", 'null': 'True', 'to': "orm['schedule.Attendee']"}), | ||
150 | 120 | 'wiki_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) | ||
151 | 121 | }, | ||
152 | 122 | 'schedule.participant': { | ||
153 | 123 | 'Meta': {'object_name': 'Participant'}, | ||
154 | 124 | 'attendee': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Attendee']"}), | ||
155 | 125 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
156 | 126 | 'meeting': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Meeting']"}), | ||
157 | 127 | 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) | ||
158 | 128 | }, | ||
159 | 129 | 'schedule.room': { | ||
160 | 130 | 'Meta': {'ordering': "('summit', 'name')", 'object_name': 'Room'}, | ||
161 | 131 | 'end_utc': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_column': "'end'", 'blank': 'True'}), | ||
162 | 132 | 'has_dial_in': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||
163 | 133 | 'icecast_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), | ||
164 | 134 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
165 | 135 | 'name': ('summit.schedule.fields.NameField', [], {'max_length': '50'}), | ||
166 | 136 | 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||
167 | 137 | 'start_utc': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_column': "'start'", 'blank': 'True'}), | ||
168 | 138 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}), | ||
169 | 139 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
170 | 140 | 'tracks': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['schedule.Track']", 'symmetrical': 'False', 'blank': 'True'}), | ||
171 | 141 | 'type': ('django.db.models.fields.CharField', [], {'default': "u'open'", 'max_length': '7'}) | ||
172 | 142 | }, | ||
173 | 143 | 'schedule.roombusy': { | ||
174 | 144 | 'Meta': {'ordering': "('room', 'start_utc', 'end_utc')", 'object_name': 'RoomBusy'}, | ||
175 | 145 | 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}), | ||
176 | 146 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
177 | 147 | 'room': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'busy_set'", 'to': "orm['schedule.Room']"}), | ||
178 | 148 | 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"}) | ||
179 | 149 | }, | ||
180 | 150 | 'schedule.slot': { | ||
181 | 151 | 'Meta': {'ordering': "('summit', 'start_utc', 'end_utc')", 'object_name': 'Slot'}, | ||
182 | 152 | 'end_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'end'"}), | ||
183 | 153 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
184 | 154 | 'start_utc': ('django.db.models.fields.DateTimeField', [], {'db_column': "'start'"}), | ||
185 | 155 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}), | ||
186 | 156 | 'type': ('django.db.models.fields.CharField', [], {'default': "u'open'", 'max_length': '7'}) | ||
187 | 157 | }, | ||
188 | 158 | 'schedule.summit': { | ||
189 | 159 | 'Meta': {'ordering': "('name',)", 'object_name': 'Summit'}, | ||
190 | 160 | 'date_end': ('django.db.models.fields.DateField', [], {'null': 'True'}), | ||
191 | 161 | 'date_start': ('django.db.models.fields.DateField', [], {'null': 'True'}), | ||
192 | 162 | 'description': ('django.db.models.fields.TextField', [], {'max_length': '2047', 'blank': 'True'}), | ||
193 | 163 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
194 | 164 | 'last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||
195 | 165 | 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), | ||
196 | 166 | 'name': ('summit.schedule.fields.NameField', [], {'max_length': '50'}), | ||
197 | 167 | 'state': ('django.db.models.fields.CharField', [], {'default': "u'sponsor'", 'max_length': '10'}), | ||
198 | 168 | 'timezone': ('django.db.models.fields.CharField', [], {'max_length': '50'}), | ||
199 | 169 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
200 | 170 | }, | ||
201 | 171 | 'schedule.summitsprint': { | ||
202 | 172 | 'Meta': {'ordering': "('summit', 'import_url')", 'object_name': 'SummitSprint'}, | ||
203 | 173 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
204 | 174 | 'import_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), | ||
205 | 175 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sprint_set'", 'to': "orm['schedule.Summit']"}) | ||
206 | 176 | }, | ||
207 | 177 | 'schedule.topic': { | ||
208 | 178 | 'Meta': {'ordering': "('summit', 'title')", 'object_name': 'Topic'}, | ||
209 | 179 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
210 | 180 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}), | ||
211 | 181 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
212 | 182 | }, | ||
213 | 183 | 'schedule.track': { | ||
214 | 184 | 'Meta': {'ordering': "('summit', 'title', 'slug')", 'object_name': 'Track'}, | ||
215 | 185 | 'color': ('django.db.models.fields.CharField', [], {'default': "'FFFFFF'", 'max_length': '6'}), | ||
216 | 186 | 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
217 | 187 | 'slug': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), | ||
218 | 188 | 'summit': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['schedule.Summit']"}), | ||
219 | 189 | 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
220 | 190 | } | ||
221 | 191 | } | ||
222 | 192 | |||
223 | 193 | complete_apps = ['schedule'] | ||
224 | 0 | 194 | ||
225 | === modified file 'summit/schedule/models/meetingmodel.py' | |||
226 | --- summit/schedule/models/meetingmodel.py 2011-09-14 01:00:37 +0000 | |||
227 | +++ summit/schedule/models/meetingmodel.py 2011-09-15 20:51:24 +0000 | |||
228 | @@ -90,6 +90,7 @@ | |||
229 | 90 | verbose_name="Pad URL", null=True, blank=True) | 90 | verbose_name="Pad URL", null=True, blank=True) |
230 | 91 | slots = models.IntegerField(default=1) | 91 | slots = models.IntegerField(default=1) |
231 | 92 | private = models.BooleanField(default=False) | 92 | private = models.BooleanField(default=False) |
232 | 93 | requires_dial_in = models.BooleanField(default=False) | ||
233 | 93 | # FIXME attendees must be for the same summit | 94 | # FIXME attendees must be for the same summit |
234 | 94 | # (will require js magic in admin to refresh the boxes) | 95 | # (will require js magic in admin to refresh the boxes) |
235 | 95 | drafter = models.ForeignKey(Attendee, null=True, blank=True, | 96 | drafter = models.ForeignKey(Attendee, null=True, blank=True, |
236 | @@ -343,6 +344,10 @@ | |||
237 | 343 | if not room.available(this_slot): | 344 | if not room.available(this_slot): |
238 | 344 | raise Meeting.SchedulingError("Room is not available") | 345 | raise Meeting.SchedulingError("Room is not available") |
239 | 345 | 346 | ||
240 | 347 | if self.requires_dial_in: | ||
241 | 348 | if not room.has_dial_in: | ||
242 | 349 | raise Meeting.SchedulingError("Room has no dial-in capability") | ||
243 | 350 | |||
244 | 346 | # Work out who is busy in this slot | 351 | # Work out who is busy in this slot |
245 | 347 | busy = set() | 352 | busy = set() |
246 | 348 | for agenda in this_slot.agenda_set.all(): | 353 | for agenda in this_slot.agenda_set.all(): |
247 | 349 | 354 | ||
248 | === modified file 'summit/schedule/models/roommodel.py' | |||
249 | --- summit/schedule/models/roommodel.py 2011-05-15 01:11:24 +0000 | |||
250 | +++ summit/schedule/models/roommodel.py 2011-09-15 20:51:24 +0000 | |||
251 | @@ -51,6 +51,10 @@ | |||
252 | 51 | verbose_name="End (UTC)") | 51 | verbose_name="End (UTC)") |
253 | 52 | icecast_url = models.URLField(blank=True, verify_exists=False, | 52 | icecast_url = models.URLField(blank=True, verify_exists=False, |
254 | 53 | verbose_name="Icecast URL") | 53 | verbose_name="Icecast URL") |
255 | 54 | |||
256 | 55 | # Whether the room has dial-in capability | ||
257 | 56 | has_dial_in = models.BooleanField(default=False) | ||
258 | 57 | |||
259 | 54 | # people who cannot be scheduled here | 58 | # people who cannot be scheduled here |
260 | 55 | # voip, listen-only and icecast urls | 59 | # voip, listen-only and icecast urls |
261 | 56 | class Meta: | 60 | class Meta: |
262 | 57 | 61 | ||
263 | === modified file 'summit/schedule/tests.py' | |||
264 | --- summit/schedule/tests.py 2011-09-15 17:22:40 +0000 | |||
265 | +++ summit/schedule/tests.py 2011-09-15 20:51:24 +0000 | |||
266 | @@ -66,6 +66,44 @@ | |||
267 | 66 | Meeting.SchedulingError, | 66 | Meeting.SchedulingError, |
268 | 67 | meeting.check_schedule, agenda.slot, agenda.room) | 67 | meeting.check_schedule, agenda.slot, agenda.room) |
269 | 68 | 68 | ||
270 | 69 | def make_open_slot(self): | ||
271 | 70 | now = datetime.datetime.utcnow() | ||
272 | 71 | one_hour = datetime.timedelta(0, 3600) | ||
273 | 72 | slot = factory.make_one( | ||
274 | 73 | Slot, | ||
275 | 74 | start_utc=now+one_hour, | ||
276 | 75 | end_utc=now+one_hour+one_hour, | ||
277 | 76 | type='open') | ||
278 | 77 | return slot | ||
279 | 78 | |||
280 | 79 | def test_check_schedule_errors_on_no_dial_in(self): | ||
281 | 80 | slot = self.make_open_slot() | ||
282 | 81 | room = factory.make_one(Room, has_dial_in=False, summit=slot.summit, name="testroom") | ||
283 | 82 | meeting = factory.make_one(Meeting, requires_dial_in=True, summit=slot.summit, name="testmeeting") | ||
284 | 83 | try: | ||
285 | 84 | meeting.check_schedule(slot, room) | ||
286 | 85 | except meeting.SchedulingError, e: | ||
287 | 86 | print e | ||
288 | 87 | self.assertEqual("Room has no dial-in capability", e.message) | ||
289 | 88 | return | ||
290 | 89 | self.fail("SchedulingError not thrown") | ||
291 | 90 | |||
292 | 91 | def test_try_schedule_into_refuses_room_without_dial_in(self): | ||
293 | 92 | slot = self.make_open_slot() | ||
294 | 93 | room = factory.make_one(Room, has_dial_in=False, summit=slot.summit, name="testroom") | ||
295 | 94 | meeting = factory.make_one(Meeting, requires_dial_in=True, summit=slot.summit, name="testmeeting") | ||
296 | 95 | |||
297 | 96 | self.assertEqual(False, meeting.try_schedule_into([room])) | ||
298 | 97 | self.assertEqual(0, meeting.agenda_set.all().count()) | ||
299 | 98 | |||
300 | 99 | def test_try_schedule_into_allows_room_with_dial_in(self): | ||
301 | 100 | slot = self.make_open_slot() | ||
302 | 101 | room = factory.make_one(Room, has_dial_in=True, summit=slot.summit, name="testroom") | ||
303 | 102 | meeting = factory.make_one(Meeting, requires_dial_in=True, summit=slot.summit, name="testmeeting") | ||
304 | 103 | |||
305 | 104 | self.assertEqual(True, meeting.try_schedule_into([room])) | ||
306 | 105 | self.assertEqual(1, meeting.agenda_set.all().count()) | ||
307 | 106 | |||
308 | 69 | 107 | ||
309 | 70 | class ICalTestCase(djangotest.TestCase): | 108 | class ICalTestCase(djangotest.TestCase): |
310 | 71 | 109 |
Well, the admin site was easier than I thought, so I've pushed
that now too.