Merge lp:~daker/loco-team-portal/fix.960695.events-app2 into lp:loco-team-portal
- fix.960695.events-app2
- Merge into 0.2
Proposed by
Adnane Belmadiaf
on 2012-06-30
| Status: | Merged |
|---|---|
| Approved by: | Chris Johnston on 2012-06-30 |
| Approved revision: | 540 |
| Merged at revision: | 540 |
| Proposed branch: | lp:~daker/loco-team-portal/fix.960695.events-app2 |
| Merge into: | lp:loco-team-portal |
| Diff against target: |
1008 lines (+142/-127) 5 files modified
loco_directory/events/forms.py (+26/-22) loco_directory/events/models.py (+23/-16) loco_directory/events/tests.py (+2/-8) loco_directory/events/urls.py (+4/-4) loco_directory/events/views.py (+87/-77) |
| To merge this branch: | bzr merge lp:~daker/loco-team-portal/fix.960695.events-app2 |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Chris Johnston | 2012-06-30 | Approve on 2012-06-30 | |
|
Review via email:
|
|||
Commit Message
Fixed the events app to passe pylint checkers
Description of the Change
To post a comment you must log in.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
| 1 | === modified file 'loco_directory/events/forms.py' |
| 2 | --- loco_directory/events/forms.py 2012-06-10 19:08:39 +0000 |
| 3 | +++ loco_directory/events/forms.py 2012-06-30 22:47:18 +0000 |
| 4 | @@ -9,10 +9,10 @@ |
| 5 | from common.forms import RenderableMixin |
| 6 | from userprofiles.models import UserProfile |
| 7 | |
| 8 | -import pytz |
| 9 | import itertools |
| 10 | import datetime |
| 11 | |
| 12 | + |
| 13 | def grouped_user_list(teams): |
| 14 | other_members, team_members = [], [] |
| 15 | for profile in UserProfile.objects.filter(user__groups__name__in=[t.lp_name for t in teams]): |
| 16 | @@ -24,16 +24,18 @@ |
| 17 | (_('Team members'), team_members), |
| 18 | (_('Other users'), other_members)] |
| 19 | |
| 20 | + |
| 21 | def validate_tag(tag): |
| 22 | if tag.startswith('#'): |
| 23 | tag = tag[1:] |
| 24 | - for delim in [ " ", ",", "#" ]: |
| 25 | + for delim in [" ", ",", "#"]: |
| 26 | if delim in tag: |
| 27 | raise forms.ValidationError(_(u'Please just set one tag.')) |
| 28 | return tag |
| 29 | |
| 30 | + |
| 31 | class BaseEventForm(forms.ModelForm, RenderableMixin): |
| 32 | - """ |
| 33 | + """ |
| 34 | a form to create/update a BaseEvent |
| 35 | """ |
| 36 | class Meta: |
| 37 | @@ -44,7 +46,7 @@ |
| 38 | css = {'all': ( |
| 39 | '/media/jquery-ui/css/css/smoothness/jquery-ui.css', |
| 40 | '/media/jquery-ui-timepicker/css/ui-lightness/ui.timepickr.css', |
| 41 | - '/media/css/colortip-1.0-jquery.css', |
| 42 | + '/media/css/colortip-1.0-jquery.css', |
| 43 | )} |
| 44 | js = ( |
| 45 | '/media/jquery/jquery.js', |
| 46 | @@ -54,12 +56,12 @@ |
| 47 | '/media/js/colortip-1.0-jquery.js', |
| 48 | '/media/js/events-ui.js', |
| 49 | ) |
| 50 | - |
| 51 | + |
| 52 | def __init__(self, *args, **kargs): |
| 53 | super(BaseEventForm, self).__init__(*args, **kargs) |
| 54 | self.fields['date_begin'].widget = forms.SplitDateTimeWidget() |
| 55 | self.fields['date_end'].widget = forms.SplitDateTimeWidget() |
| 56 | - |
| 57 | + |
| 58 | def clean(self): |
| 59 | begin = self.cleaned_data.get('date_begin') |
| 60 | end = self.cleaned_data.get('date_end') |
| 61 | @@ -67,14 +69,15 @@ |
| 62 | raise forms.ValidationError("Events can not end before they start.") |
| 63 | return self.cleaned_data |
| 64 | |
| 65 | + |
| 66 | class TeamEventForm(BaseEventForm): |
| 67 | - """ |
| 68 | + """ |
| 69 | a form to create/update a TeamEvent |
| 70 | """ |
| 71 | class Meta(BaseEventForm.Meta): |
| 72 | model = TeamEvent |
| 73 | exclude = ('teams', 'date_created') |
| 74 | - |
| 75 | + |
| 76 | def __init__(self, teams=[], *args, **kargs): |
| 77 | super(TeamEventForm, self).__init__(*args, **kargs) |
| 78 | self.teams = teams |
| 79 | @@ -86,7 +89,7 @@ |
| 80 | self.fields['global_event'].choices.insert(0, ('', '---------')) |
| 81 | self.initial['date_begin'] = self.instance.local_date_begin |
| 82 | self.initial['date_end'] = self.instance.local_date_end |
| 83 | - |
| 84 | + |
| 85 | def clean(self): |
| 86 | venue = self.cleaned_data.get('venue') |
| 87 | if venue is not None: |
| 88 | @@ -102,7 +105,7 @@ |
| 89 | self.cleaned_data['date_begin'] = self.teams[0].fromlocaltime(begin) |
| 90 | self.cleaned_data['date_end'] = self.teams[0].fromlocaltime(end) |
| 91 | return self.cleaned_data |
| 92 | - |
| 93 | + |
| 94 | def grouped_venue_list(self): |
| 95 | """ |
| 96 | Returns a list of venues grouped by country |
| 97 | @@ -129,7 +132,7 @@ |
| 98 | venues_team = Venue.objects.filter(country__team__in=self.teams).order_by('country', 'spr', 'city') |
| 99 | venues_other = Venue.objects.all().exclude(country__team__in=self.teams).order_by('country', 'spr', 'city') |
| 100 | venues = itertools.chain(venues_team, venues_other) |
| 101 | - |
| 102 | + |
| 103 | # Ordered by country so we can tell when we're done with one |
| 104 | # and starting another |
| 105 | for venue in venues: |
| 106 | @@ -146,26 +149,26 @@ |
| 107 | # Add venue to the current country group |
| 108 | country_choices.append((venue.id, str(venue))) |
| 109 | |
| 110 | - |
| 111 | # Add the last country group to the list if it's non-empty |
| 112 | if len(country_choices) > 0: |
| 113 | venue_choices.append((current_country, country_choices)) |
| 114 | - |
| 115 | + |
| 116 | return venue_choices |
| 117 | - |
| 118 | - |
| 119 | + |
| 120 | + |
| 121 | class GlobalEventForm(BaseEventForm): |
| 122 | - """ |
| 123 | + """ |
| 124 | a form to create/update a GlobalEvent |
| 125 | """ |
| 126 | class Meta(BaseEventForm.Meta): |
| 127 | model = GlobalEvent |
| 128 | |
| 129 | - def clean(self): |
| 130 | + def clean(self): |
| 131 | self.cleaned_data['microbloghashtag'] = validate_tag(self.cleaned_data['microbloghashtag']) |
| 132 | self.cleaned_data['pictag'] = validate_tag(self.cleaned_data['pictag']) |
| 133 | return self.cleaned_data |
| 134 | |
| 135 | + |
| 136 | class AttendeeRegistrationForm(forms.ModelForm, RenderableMixin): |
| 137 | """ |
| 138 | a form to create/update an Attendee object |
| 139 | @@ -179,6 +182,7 @@ |
| 140 | model = Attendee |
| 141 | exclude = ('attendee_profile', 'team_event') |
| 142 | |
| 143 | + |
| 144 | class TeamEventCommentForm(forms.ModelForm, RenderableMixin): |
| 145 | """ |
| 146 | a form to comment a team event |
| 147 | @@ -189,13 +193,14 @@ |
| 148 | |
| 149 | class Media: |
| 150 | css = {'all': ( |
| 151 | - '/media/css/colortip-1.0-jquery.css', |
| 152 | + '/media/css/colortip-1.0-jquery.css', |
| 153 | )} |
| 154 | js = ( |
| 155 | '/media/jquery/jquery.js', |
| 156 | '/media/js/colortip-1.0-jquery.js', |
| 157 | ) |
| 158 | |
| 159 | + |
| 160 | class FilterHistoryList(forms.Form): |
| 161 | """ |
| 162 | a form to filter event history list |
| 163 | @@ -206,14 +211,14 @@ |
| 164 | scope = forms.ChoiceField(choices) |
| 165 | |
| 166 | now = datetime.datetime.now().strftime("%Y-%m") |
| 167 | - filtering = forms.CharField(required=False, initial=now) |
| 168 | + filtering = forms.CharField(required=False, initial=now) |
| 169 | |
| 170 | class Media: |
| 171 | css = {'all': ( |
| 172 | '/media/jquery-ui/css/css/smoothness/jquery-ui.css', |
| 173 | '/media/jquery-ui-timepicker/css/ui-lightness/ui.timepickr.css', |
| 174 | - '/media/css/colortip-1.0-jquery.css', |
| 175 | - '/media/css/newstyle.css', |
| 176 | + '/media/css/colortip-1.0-jquery.css', |
| 177 | + '/media/css/newstyle.css', |
| 178 | )} |
| 179 | js = ( |
| 180 | '/media/jquery/jquery.js', |
| 181 | @@ -223,4 +228,3 @@ |
| 182 | '/media/js/colortip-1.0-jquery.js', |
| 183 | '/media/js/events-ui.js', |
| 184 | ) |
| 185 | - |
| 186 | |
| 187 | === modified file 'loco_directory/events/models.py' |
| 188 | --- loco_directory/events/models.py 2012-06-20 10:32:02 +0000 |
| 189 | +++ loco_directory/events/models.py 2012-06-30 22:47:18 +0000 |
| 190 | @@ -15,6 +15,7 @@ |
| 191 | import pytz |
| 192 | import datetime |
| 193 | |
| 194 | + |
| 195 | class BaseEvent(models.Model): |
| 196 | """ |
| 197 | a simple basic event |
| 198 | @@ -28,7 +29,7 @@ |
| 199 | |
| 200 | def __unicode__(self): |
| 201 | return self.name |
| 202 | - |
| 203 | + |
| 204 | def as_ical(self, cal): |
| 205 | """ |
| 206 | return a event as ical |
| 207 | @@ -44,12 +45,13 @@ |
| 208 | def is_past(self): |
| 209 | return self.date_end > datetime.datetime.today() |
| 210 | |
| 211 | + |
| 212 | class GlobalEventManager(models.Manager): |
| 213 | """ manager for a global event """ |
| 214 | def next_events(self): |
| 215 | """ a list with all upcoming global events """ |
| 216 | return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end') |
| 217 | - |
| 218 | + |
| 219 | def history_events(self): |
| 220 | """ all global events in history """ |
| 221 | return self.filter(date_end__lt=datetime.datetime.now()).order_by('date_end') |
| 222 | @@ -62,6 +64,7 @@ |
| 223 | """ return the last 5 active Team events for this global event""" |
| 224 | return TeamEvent.objects.filter(global_event__id__exact=self.id).order_by('?')[5:] |
| 225 | |
| 226 | + |
| 227 | class GlobalEvent(BaseEvent): |
| 228 | """ |
| 229 | a global event. other events can attend to a global event |
| 230 | @@ -70,7 +73,7 @@ |
| 231 | pictag = models.CharField(max_length=50, help_text=_('tag used in web albums like; picasa, flickr, and more'), verbose_name=_('Picture Tag'), null=True, blank=True) |
| 232 | channel = models.CharField(help_text=_('Channel for the Event hosted on the freenode IRC network. Ex. #ubuntu-locoteams'), max_length=25, verbose_name=_('Event Channel'), blank=True, null=True) |
| 233 | activities = models.TextField(help_text=_('Activities to do during the Event'), blank=True, null=True) |
| 234 | - |
| 235 | + |
| 236 | objects = GlobalEventManager() |
| 237 | |
| 238 | def __unicode__(self): |
| 239 | @@ -79,23 +82,24 @@ |
| 240 | @models.permalink |
| 241 | def get_absolute_url(self): |
| 242 | return ('global-event-detail', [str(self.id)]) |
| 243 | - |
| 244 | + |
| 245 | def get_participating(self): |
| 246 | attendees = 0 |
| 247 | for attendee in Attendee.objects.filter(team_event__global_event=self, promise='sure'): |
| 248 | attendees += attendee.guests + 1 |
| 249 | locos = len(Team.objects.filter(teamevent__global_event=self).distinct()) |
| 250 | countries = len(Country.objects.filter(team__teamevent__global_event=self).distinct()) |
| 251 | - return _('%(attendees)d people from %(locos)d LoCos and %(countries)d countries are participating in this event!' % {'attendees': attendees, |
| 252 | - 'locos': locos, |
| 253 | + return _('%(attendees)d people from %(locos)d LoCos and %(countries)d countries are participating in this event!' % {'attendees': attendees, |
| 254 | + 'locos': locos, |
| 255 | 'countries': countries}) |
| 256 | |
| 257 | + |
| 258 | class TeamEventManager(models.Manager): |
| 259 | """ manager for a team event """ |
| 260 | def next_3_events(self): |
| 261 | """ a list with the next 3 events """ |
| 262 | return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end')[:3] |
| 263 | - |
| 264 | + |
| 265 | def next_5_events(self): |
| 266 | """ a list with the next 5 events """ |
| 267 | return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end')[:5] |
| 268 | @@ -113,10 +117,11 @@ |
| 269 | |
| 270 | def random_5_attendees(self): |
| 271 | return Attendee.objects.filter(event__id__exact=self.id).order_by('?')[5:] |
| 272 | - |
| 273 | + |
| 274 | def has_location(self): |
| 275 | return self.filter(venue__longitude__isnull=False, venue__latitude__isnull=False) |
| 276 | |
| 277 | + |
| 278 | class TeamEvent(BaseEvent, LocalTimeMixin): |
| 279 | """ |
| 280 | a event of one or more teams |
| 281 | @@ -125,7 +130,7 @@ |
| 282 | contact = models.ForeignKey(UserProfile, verbose_name=_('Event Contact'), null=True, help_text=_('Contact person for this event.')) |
| 283 | global_event = models.ForeignKey(GlobalEvent, help_text=_('this team event is part of the selected global event'), verbose_name=_('Related Global Event'), blank=True, null=True) |
| 284 | venue = models.ForeignKey(Venue, help_text=_('Venue for the Event'), verbose_name=_('Event Venue'), blank=True, null=True) |
| 285 | - channel = models.CharField(help_text=_('Channel for the Event hosted on the freenode IRC network. Ex. #ubuntu-us-fl'), max_length=25, verbose_name=_('Event Channel'), blank=True, null=True) |
| 286 | + channel = models.CharField(help_text=_('Channel for the Event hosted on the freenode IRC network. Ex. #ubuntu-us-fl'), max_length=25, verbose_name=_('Event Channel'), blank=True, null=True) |
| 287 | registration = models.URLField(verbose_name=_('Registration URL'), help_text=_('URL to register attendance (leave blank to use the built-in registration system)'), max_length=200, verify_exists=False, blank=True, null=True) |
| 288 | template = 'events/team_event_li.inc.html' |
| 289 | |
| 290 | @@ -151,19 +156,20 @@ |
| 291 | return timezone |
| 292 | tz = property(get_tz) |
| 293 | |
| 294 | - |
| 295 | def get_local_begin(self): |
| 296 | return self.tolocaltime(self.date_begin) |
| 297 | + |
| 298 | def set_local_begin(self, local_begin): |
| 299 | self.date_begin = self.fromlocaltime(local_begin) |
| 300 | local_date_begin = property(get_local_begin) |
| 301 | |
| 302 | def get_local_end(self): |
| 303 | return self.tolocaltime(self.date_end) |
| 304 | + |
| 305 | def set_local_end(self, local_end): |
| 306 | self.date_end = self.fromlocaltime(local_end) |
| 307 | local_date_end = property(get_local_end, set_local_end) |
| 308 | - |
| 309 | + |
| 310 | def attending(self): |
| 311 | return self.attendee_set.filter(promise__exact='sure') |
| 312 | |
| 313 | @@ -178,7 +184,7 @@ |
| 314 | return self.teams.all()[0] |
| 315 | except: |
| 316 | print 'Event %s has no team' % self.id |
| 317 | - return {'lp_name':'no-team'} |
| 318 | + return {'lp_name': 'no-team'} |
| 319 | |
| 320 | def is_attending(self, user): |
| 321 | if user.is_authenticated(): |
| 322 | @@ -206,7 +212,7 @@ |
| 323 | date_created = models.DateTimeField(help_text=_('Comment date and time'), default=datetime.datetime.now(), db_index=True) |
| 324 | commenter_profile = models.ForeignKey(UserProfile, null=True) |
| 325 | comment = models.TextField(help_text=_('Enter your comment for this event.'), db_index=True) |
| 326 | - |
| 327 | + |
| 328 | def __unicode__(self): |
| 329 | return "Team Event: %s . Comment: %s" % (self.team_event.name, self.comment) |
| 330 | |
| 331 | @@ -215,6 +221,7 @@ |
| 332 | return self.team_event.venue.tolocaltime(self.date_created) |
| 333 | else: |
| 334 | return self.date_created |
| 335 | + |
| 336 | def set_local_created(self, local_created): |
| 337 | if self.team_event.venue: |
| 338 | self.date_created = self.team_event.venue.fromlocaltime(local_created) |
| 339 | @@ -222,11 +229,12 @@ |
| 340 | self.date_created = local_created |
| 341 | local_date_created = property(get_local_created, set_local_created) |
| 342 | |
| 343 | + |
| 344 | class Attendee(models.Model): |
| 345 | """ |
| 346 | a event attendee |
| 347 | """ |
| 348 | - |
| 349 | + |
| 350 | team_event = models.ForeignKey(TeamEvent, help_text=_('the Team Event')) |
| 351 | attendee_profile = models.ForeignKey(UserProfile, help_text=_('the name of the attendee'), null=True) |
| 352 | promise = models.CharField(verbose_name=_('Attending Status'), max_length=50, choices=ATTENDEE_PROMISE_CHOICES) |
| 353 | @@ -234,7 +242,6 @@ |
| 354 | |
| 355 | class Meta: |
| 356 | unique_together = ('team_event', 'attendee_profile') |
| 357 | - |
| 358 | + |
| 359 | def __unicode__(self): |
| 360 | return self.attendee_profile.user.username |
| 361 | - |
| 362 | |
| 363 | === modified file 'loco_directory/events/tests.py' |
| 364 | --- loco_directory/events/tests.py 2011-07-17 18:11:38 +0000 |
| 365 | +++ loco_directory/events/tests.py 2012-06-30 22:47:18 +0000 |
| 366 | @@ -18,20 +18,17 @@ |
| 367 | def setUp(self): |
| 368 | # setup country record for testing |
| 369 | self.country = Country.objects.create(name='Test Country') |
| 370 | - |
| 371 | # setup team record for testing |
| 372 | self.team = Team.objects.create( |
| 373 | lp_name='test-team', |
| 374 | name='Test Team', |
| 375 | ) |
| 376 | self.team.countries.add(self.country) |
| 377 | - |
| 378 | # setup venue record for testing |
| 379 | self.venue = Venue.objects.create( |
| 380 | name='Test Venue', |
| 381 | country=self.country, |
| 382 | ) |
| 383 | - |
| 384 | # setup event record for testing |
| 385 | self.event = TeamEvent.objects.create( |
| 386 | name='Test Event', |
| 387 | @@ -40,7 +37,6 @@ |
| 388 | venue=self.venue, |
| 389 | ) |
| 390 | self.event.teams.add(self.team) |
| 391 | - |
| 392 | # setup user record for testing |
| 393 | self.team_group = Group.objects.create( |
| 394 | name=self.team.lp_name, |
| 395 | @@ -51,11 +47,10 @@ |
| 396 | self.user.set_password('test') |
| 397 | self.user.groups.add(self.team_group) |
| 398 | self.user.save() |
| 399 | - |
| 400 | |
| 401 | def test_large_guest_validation(self): |
| 402 | 'Validate the guests size and show friendly error message when too big' |
| 403 | - |
| 404 | + |
| 405 | # register attendence form data |
| 406 | path = '/events/%s/%s/register/' % (self.team.lp_name, self.event.id) |
| 407 | data = { |
| 408 | @@ -64,12 +59,11 @@ |
| 409 | } |
| 410 | # login so we're not redirected when posting the form data |
| 411 | self.client.login(username='testuser', password='test') |
| 412 | - |
| 413 | # post the form data |
| 414 | response = self.client.post(path, data) |
| 415 | |
| 416 | # should get a 200 if the integer size is caught by form validation |
| 417 | self.assertEquals(response.status_code, 200) |
| 418 | - |
| 419 | + |
| 420 | # check that the user friendly error message exists in the response |
| 421 | self.assertContains(response, 'Ensure this value is less than or equal to 100.') |
| 422 | |
| 423 | === modified file 'loco_directory/events/urls.py' |
| 424 | --- loco_directory/events/urls.py 2012-04-14 22:10:09 +0000 |
| 425 | +++ loco_directory/events/urls.py 2012-06-30 22:47:18 +0000 |
| 426 | @@ -1,14 +1,14 @@ |
| 427 | from django.conf.urls.defaults import * |
| 428 | |
| 429 | urlpatterns = patterns('', |
| 430 | - #all events |
| 431 | + #all events |
| 432 | url(r'^$', 'events.views.event_list', name='event-list'), |
| 433 | url(r'^history/$', 'events.views.event_history_list', name='event-history-list'), |
| 434 | |
| 435 | #special events |
| 436 | url(r'^globaljam/$', 'events.views.global_jam', name='global-jam-dashboard'), |
| 437 | url(r'^globaljam/dashboard/$', 'events.views.global_jam_dashboard', name='global-jam'), |
| 438 | - |
| 439 | + |
| 440 | #global events |
| 441 | url(r'^global/ical/$', 'events.views.global_event_list_ical', name='global-event-list-ical'), |
| 442 | url(r'^global/(?P<global_event_id>\d+)/detail/$', 'events.views.global_event_detail', name='global-event-detail'), |
| 443 | @@ -16,7 +16,7 @@ |
| 444 | url(r'^global/(?P<global_event_id>\d+)/update/$', 'events.views.global_event_update', name='global-event-update'), |
| 445 | url(r'^global/(?P<global_event_id>\d+)/locations/$', 'events.views.global_event_locations', name='global-event-locations'), |
| 446 | url(r'^global/add/$', 'events.views.global_event_new', name='global-event-new'), |
| 447 | - |
| 448 | + |
| 449 | #team events |
| 450 | url(r'^locations/$', 'events.views.team_event_locations', name='team-event-locations'), |
| 451 | url(r'^ical/$', 'events.views.teams_event_list_ical', name='teams-event-list-ical'), |
| 452 | @@ -30,7 +30,7 @@ |
| 453 | url(r'^(?P<team_slug>[a-zA-Z0-9\-\.\+?]+)/rss/$', 'events.views.team_events_rss', name='team-events-rss'), |
| 454 | url(r'^(?P<team_slug>[a-zA-Z0-9\-\.\+?]+)/ical/$', 'events.views.team_event_list_ical', name='team-event-list-ical'), |
| 455 | url(r'^add/$', 'events.views.team_event_select', name='team-event-select'), |
| 456 | - |
| 457 | + |
| 458 | # Old url notations |
| 459 | url(r'^team/locations/$', 'events.views.team_event_locations'), |
| 460 | url(r'^team/ical/$', 'events.views.teams_event_list_ical'), |
| 461 | |
| 462 | === modified file 'loco_directory/events/views.py' |
| 463 | --- loco_directory/events/views.py 2012-06-30 19:19:08 +0000 |
| 464 | +++ loco_directory/events/views.py 2012-06-30 22:47:18 +0000 |
| 465 | @@ -5,7 +5,6 @@ |
| 466 | from django.contrib.auth.decorators import login_required |
| 467 | from django.utils import simplejson |
| 468 | from django.utils.translation import ugettext as _ |
| 469 | -from django.core.urlresolvers import reverse |
| 470 | from django.db.models import Count |
| 471 | |
| 472 | from events.models import TeamEvent |
| 473 | @@ -19,14 +18,13 @@ |
| 474 | from forms import AttendeeRegistrationForm |
| 475 | from forms import FilterHistoryList |
| 476 | |
| 477 | -from django.db.models import Q |
| 478 | - |
| 479 | from common.utils import redirect, simple_iterator |
| 480 | from common import launchpad |
| 481 | |
| 482 | import datetime |
| 483 | import vobject |
| 484 | |
| 485 | + |
| 486 | def event_list(request): |
| 487 | """ |
| 488 | a list with all events (teamevents and globalevents) |
| 489 | @@ -37,11 +35,12 @@ |
| 490 | context = { |
| 491 | 'team_event_list': team_event_list, |
| 492 | 'global_event_list': global_event_list, |
| 493 | - 'user_is_on_lc': is_on_lc, |
| 494 | + 'user_is_on_lc': is_on_lc, |
| 495 | } |
| 496 | return render_to_response('events/event_list.html', context, |
| 497 | RequestContext(request)) |
| 498 | |
| 499 | + |
| 500 | def event_list_ical(events, name): |
| 501 | """Return any list events as an ical""" |
| 502 | filename = "%s.ics" % name.replace(' ', '-').lower() |
| 503 | @@ -57,9 +56,10 @@ |
| 504 | for event in events: |
| 505 | event.as_ical(calendar) |
| 506 | response.write(calendar.serialize()) |
| 507 | - |
| 508 | + |
| 509 | return response |
| 510 | |
| 511 | + |
| 512 | def event_ical(request, team_slug, team_event_id): |
| 513 | """ |
| 514 | Return a ical list with a single events in ical format. |
| 515 | @@ -67,6 +67,7 @@ |
| 516 | team_event_object = get_object_or_404(TeamEvent, pk=team_event_id) |
| 517 | return event_list_ical([team_event_object], team_event_object.name) |
| 518 | |
| 519 | + |
| 520 | def team_event_list_ical(request, team_slug): |
| 521 | """ |
| 522 | Return a ical list with a single team events in ical format. |
| 523 | @@ -75,18 +76,21 @@ |
| 524 | team_events = TeamEvent.objects.filter(teams__lp_name=team_slug) |
| 525 | return event_list_ical(team_events, team.name) |
| 526 | |
| 527 | + |
| 528 | def teams_event_list_ical(request): |
| 529 | """ |
| 530 | Return a ical list with team events in ical format. |
| 531 | """ |
| 532 | return event_list_ical(TeamEvent.objects.all(), 'All Ubuntu LoCo Team Events') |
| 533 | |
| 534 | + |
| 535 | def global_event_list_ical(request): |
| 536 | """ |
| 537 | Return a ical list with global events in ical format. |
| 538 | """ |
| 539 | return event_list_ical(GlobalEvent.objects.all(), 'Ubuntu Global Events') |
| 540 | |
| 541 | + |
| 542 | def event_history_list(request): |
| 543 | """ |
| 544 | a list with all historical events (teamevents and globalevents) |
| 545 | @@ -102,14 +106,13 @@ |
| 546 | scope = form.cleaned_data['scope'] |
| 547 | |
| 548 | if u'my' in scope: |
| 549 | - filtering_date = datetime.datetime.strptime(filtering,"%Y-%m") |
| 550 | + filtering_date = datetime.datetime.strptime(filtering, "%Y-%m") |
| 551 | |
| 552 | team_event_list = TeamEvent.objects.history_events().filter(date_begin__year=filtering_date.year, date_begin__month=filtering_date.month) |
| 553 | elif u'y' in scope: |
| 554 | - filtering_date = datetime.datetime.strptime(filtering,"%Y-%m") |
| 555 | + filtering_date = datetime.datetime.strptime(filtering, "%Y-%m") |
| 556 | |
| 557 | team_event_list = TeamEvent.objects.history_events().filter(date_begin__year=filtering_date.year) |
| 558 | - |
| 559 | else: |
| 560 | team_event_list = TeamEvent.objects.history_events().select_related('global_event', 'venue') |
| 561 | |
| 562 | @@ -127,10 +130,10 @@ |
| 563 | return render_to_response('events/event_history_list.html', context, |
| 564 | RequestContext(request)) |
| 565 | |
| 566 | + |
| 567 | ################################################################# |
| 568 | # Team Events |
| 569 | ################################################################# |
| 570 | - |
| 571 | def team_event_detail(request, team_slug, team_event_id): |
| 572 | """ |
| 573 | detailed view for a team event |
| 574 | @@ -141,7 +144,7 @@ |
| 575 | is_member = is_member or launchpad.is_team_member(request.user, team_object) |
| 576 | |
| 577 | if request.user.is_authenticated(): |
| 578 | - if request.method == 'POST': |
| 579 | + if request.method == 'POST': |
| 580 | form = TeamEventCommentForm(data=request.POST) |
| 581 | if form.is_valid(): |
| 582 | team_event_comment = form.save(commit=False) |
| 583 | @@ -151,7 +154,7 @@ |
| 584 | team_event_comment.commenter_profile = profile |
| 585 | team_event_comment.save() |
| 586 | request.user.message_set.create(message=_('Comment saved.')) |
| 587 | - return redirect( team_event_object ) |
| 588 | + return redirect(team_event_object) |
| 589 | else: |
| 590 | form = TeamEventCommentForm() |
| 591 | else: |
| 592 | @@ -163,16 +166,17 @@ |
| 593 | 'user_is_team_member': is_member, |
| 594 | 'form': form, |
| 595 | } |
| 596 | - return render_to_response('events/team_event_detail.html', |
| 597 | + return render_to_response('events/team_event_detail.html', |
| 598 | context, RequestContext(request)) |
| 599 | |
| 600 | + |
| 601 | @login_required |
| 602 | def team_event_delete(request, team_slug, team_event_id): |
| 603 | """ |
| 604 | delete a event |
| 605 | """ |
| 606 | team_event_object = get_object_or_404(TeamEvent, pk=team_event_id) |
| 607 | - |
| 608 | + |
| 609 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 610 | #check if user is admin or owner of a team |
| 611 | is_contact = False |
| 612 | @@ -182,24 +186,25 @@ |
| 613 | break |
| 614 | |
| 615 | if is_on_lc or is_contact: |
| 616 | - if request.method == 'POST': |
| 617 | + if request.method == 'POST': |
| 618 | team_event_object.delete() |
| 619 | request.user.message_set.create(message=_('Team Event removed.')) |
| 620 | - return redirect( 'event-list' ) |
| 621 | + return redirect('event-list') |
| 622 | else: |
| 623 | context = {'team_event_object': team_event_object} |
| 624 | return render_to_response('events/team_event_delete_confirm.html', context, RequestContext(request)) |
| 625 | |
| 626 | else: |
| 627 | request.user.message_set.create(message='%s %s' % (_('You can not remove this team event.'), _('You are not an admin/owner of the Launchpad team or on the LoCo Council.'))) |
| 628 | - return redirect( team_event_object ) |
| 629 | + return redirect(team_event_object) |
| 630 | + |
| 631 | |
| 632 | @login_required |
| 633 | def team_event_select(request): |
| 634 | teams = Team.objects.filter(lp_name__in=[g.name for g in request.user.groups.all()]) |
| 635 | if len(teams) == 0: |
| 636 | request.user.message_set.create(message='%s %s' % (_('You can not add a new team event.'), _('You are not a member of any LoCo Teams.'))) |
| 637 | - return redirect( 'event-list' ) |
| 638 | + return redirect('event-list') |
| 639 | elif len(teams) == 1: |
| 640 | from django.core import urlresolvers |
| 641 | url = urlresolvers.reverse('team-event-new', args=[teams[0].lp_name]) |
| 642 | @@ -211,38 +216,40 @@ |
| 643 | context = {'teams': teams, 'global_event_id': request.GET.get('global_event_id', None)} |
| 644 | return render_to_response('events/team_event_new_select.html', context, RequestContext(request)) |
| 645 | |
| 646 | + |
| 647 | def team_events_rss(request, team_slug): |
| 648 | team_object = get_object_or_404(Team, lp_name=team_slug) |
| 649 | events = TeamEvent.objects.filter(teams__lp_name=team_slug, date_end__gt=datetime.datetime.now()).order_by('date_begin')[:15] |
| 650 | - |
| 651 | + |
| 652 | if request.META.has_key('wsgi.url_scheme'): |
| 653 | scheme = request.META.get('wsgi.url_scheme') |
| 654 | else: |
| 655 | scheme = 'http' |
| 656 | - |
| 657 | + |
| 658 | if request.META.has_key('HTTP_HOST'): |
| 659 | host = request.META.get('HTTP_HOST') |
| 660 | else: |
| 661 | host = request.META.get('SERVER_NAME') |
| 662 | - |
| 663 | + |
| 664 | if request.META.get('SERVER_PORT', 80) == 80 or request.META.get('SERVER_PORT', 80) == 0: |
| 665 | base = '%s://%s' % (scheme, host) |
| 666 | else: |
| 667 | base = '%s://%s:%s' % (scheme, host, request.META.get('SERVER_PORT', 80)) |
| 668 | - |
| 669 | - context = {'team_object': team_object, 'events': events, 'base':base} |
| 670 | + |
| 671 | + context = {'team_object': team_object, 'events': events, 'base': base} |
| 672 | return render_to_response('events/team_events_rss.xml', context, RequestContext(request), mimetype='application/xhtml+xml') |
| 673 | |
| 674 | + |
| 675 | @login_required |
| 676 | def team_event_new(request, team_slug): |
| 677 | """ |
| 678 | new team event |
| 679 | """ |
| 680 | team_object = get_object_or_404(Team, lp_name=team_slug) |
| 681 | - |
| 682 | + |
| 683 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 684 | is_member = launchpad.is_team_member(request.user, team_object) |
| 685 | - |
| 686 | + |
| 687 | if is_on_lc or is_member: |
| 688 | global_event = None |
| 689 | if request.method == 'POST': |
| 690 | @@ -250,37 +257,36 @@ |
| 691 | if form.is_valid(): |
| 692 | team_event = form.save() |
| 693 | team_event.teams.add(team_object) |
| 694 | - team_event_id = team_event.id |
| 695 | return HttpResponseRedirect(team_event.get_absolute_url()) |
| 696 | else: |
| 697 | - form = TeamEventForm(initial={'global_event':request.GET.get('global_event_id', None)}, teams=[team_object]) |
| 698 | + form = TeamEventForm(initial={'global_event': request.GET.get('global_event_id', None)}, teams=[team_object]) |
| 699 | if request.GET.has_key('global_event_id'): |
| 700 | global_event = get_object_or_404(GlobalEvent, pk=request.GET.get('global_event_id')) |
| 701 | - |
| 702 | context = { |
| 703 | 'team_object': team_object, |
| 704 | 'form': form, |
| 705 | 'global_event': global_event, |
| 706 | } |
| 707 | - return render_to_response('events/team_event_new.html', |
| 708 | + return render_to_response('events/team_event_new.html', |
| 709 | context, RequestContext(request)) |
| 710 | else: |
| 711 | # XXX: Once we move to a new ACL system, this needs fixing. |
| 712 | request.user.message_set.create(message='%s %s' % (_('You can not add a new event for this team.'), _('You are not a member of the team or on the LoCo Council.'))) |
| 713 | - return redirect( team_object ) |
| 714 | + return redirect(team_object) |
| 715 | + |
| 716 | |
| 717 | @login_required |
| 718 | def team_event_copy(request, team_slug, team_event_id): |
| 719 | """ |
| 720 | new team event |
| 721 | """ |
| 722 | - |
| 723 | + |
| 724 | team_event = get_object_or_404(TeamEvent, pk=team_event_id) |
| 725 | team_object = team_event.teams.all()[0] |
| 726 | |
| 727 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 728 | is_member = launchpad.is_team_member(request.user, team_object) |
| 729 | - |
| 730 | + |
| 731 | if is_on_lc or is_member: |
| 732 | if request.method == 'POST': |
| 733 | form = TeamEventForm(instance=team_event, data=request.POST, teams=team_event.teams.all()) |
| 734 | @@ -288,21 +294,20 @@ |
| 735 | if form.is_valid(): |
| 736 | team_event = form.save() |
| 737 | team_event.teams.add(team_object) |
| 738 | - team_event_id = team_event.id |
| 739 | return HttpResponseRedirect(team_event.get_absolute_url()) |
| 740 | else: |
| 741 | form = TeamEventForm(instance=team_event, teams=team_event.teams.all()) |
| 742 | - |
| 743 | context = { |
| 744 | 'team_object': team_object, |
| 745 | 'form': form, |
| 746 | } |
| 747 | - return render_to_response('events/team_event_new.html', |
| 748 | + return render_to_response('events/team_event_new.html', |
| 749 | context, RequestContext(request)) |
| 750 | else: |
| 751 | # XXX: Once we move to a new ACL system, this needs fixing. |
| 752 | request.user.message_set.create(message='%s %s' % (_('You can not add a new event for this team.'), _('You are not a member of the team or on the LoCo Council.'))) |
| 753 | - return redirect( team_object ) |
| 754 | + return redirect(team_object) |
| 755 | + |
| 756 | |
| 757 | @login_required |
| 758 | def team_event_update(request, team_slug, team_event_id): |
| 759 | @@ -316,27 +321,28 @@ |
| 760 | if launchpad.is_team_member(request.user, team): |
| 761 | is_member = True |
| 762 | break |
| 763 | - |
| 764 | + |
| 765 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 766 | - |
| 767 | + |
| 768 | if is_on_lc or is_member: |
| 769 | - if request.method == 'POST': |
| 770 | + if request.method == 'POST': |
| 771 | form = TeamEventForm(data=request.POST, instance=team_event_object, teams=team_event_object.teams.all()) |
| 772 | if form.is_valid(): |
| 773 | form.save() |
| 774 | request.user.message_set.create(message=_('Team Event updated.')) |
| 775 | - return redirect( team_event_object ) |
| 776 | + return redirect(team_event_object) |
| 777 | else: |
| 778 | form = TeamEventForm(instance=team_event_object, teams=team_event_object.teams.all()) |
| 779 | - |
| 780 | + |
| 781 | context = { |
| 782 | 'form': form, |
| 783 | } |
| 784 | - return render_to_response('events/team_event_update.html', |
| 785 | + return render_to_response('events/team_event_update.html', |
| 786 | context, RequestContext(request)) |
| 787 | else: |
| 788 | request.user.message_set.create(message='%s %s' % (_('You can not update this team event.'), _('You are not a member of the team or on the LoCo Council.'))) |
| 789 | - return redirect( team_event_object ) |
| 790 | + return redirect(team_event_object) |
| 791 | + |
| 792 | |
| 793 | @login_required |
| 794 | def team_event_register(request, team_slug, team_event_id): |
| 795 | @@ -350,33 +356,32 @@ |
| 796 | from userprofiles.models import create_profile |
| 797 | profile = create_profile(request.user.username) |
| 798 | attendee_object = Attendee(team_event=team_event_object, attendee_profile=profile) |
| 799 | - |
| 800 | - if request.method == 'POST': |
| 801 | + |
| 802 | + if request.method == 'POST': |
| 803 | form = AttendeeRegistrationForm(instance=attendee_object, data=request.POST) |
| 804 | if form.is_valid(): |
| 805 | form.save() |
| 806 | request.user.message_set.create(message=_('Your registration has been saved.')) |
| 807 | - return redirect( team_event_object ) |
| 808 | + return redirect(team_event_object) |
| 809 | else: |
| 810 | - form = AttendeeRegistrationForm(instance=attendee_object, initial={'guests':0}) |
| 811 | + form = AttendeeRegistrationForm(instance=attendee_object, initial={'guests': 0}) |
| 812 | |
| 813 | is_past_event = False |
| 814 | if team_event_object.date_end < datetime.datetime.now(): |
| 815 | - is_past_event = True |
| 816 | - |
| 817 | + is_past_event = True |
| 818 | + |
| 819 | context = { |
| 820 | 'form': form, |
| 821 | 'is_past_event': is_past_event, |
| 822 | } |
| 823 | |
| 824 | - return render_to_response('events/team_event_register.html', |
| 825 | + return render_to_response('events/team_event_register.html', |
| 826 | context, RequestContext(request)) |
| 827 | |
| 828 | |
| 829 | ################################################################# |
| 830 | # Global Events |
| 831 | ################################################################# |
| 832 | - |
| 833 | def global_event_detail(request, global_event_id): |
| 834 | """ |
| 835 | detailed view for a global event |
| 836 | @@ -387,7 +392,6 @@ |
| 837 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 838 | |
| 839 | events_without_venue = global_event_object.teamevent_set.filter(venue__isnull=True) |
| 840 | - events_without_continent = global_event_object.teamevent_set.filter(venue__country__continents__isnull=True) |
| 841 | country_ids = [a.venue.country.id for a in global_event_object.teamevent_set.filter(venue__isnull=False, |
| 842 | venue__country__continents__isnull=False)] |
| 843 | country_without_continents_ids = [a.venue.country.id \ |
| 844 | @@ -406,35 +410,37 @@ |
| 845 | 'global_event_object': global_event_object, |
| 846 | 'add_team_event': add_team_event, |
| 847 | 'events_without_venue': events_without_venue, |
| 848 | - 'user_is_on_lc': is_on_lc, |
| 849 | + 'user_is_on_lc': is_on_lc, |
| 850 | 'continents': continents, |
| 851 | 'countries': countries, |
| 852 | 'countries_without_continents': countries_without_continents, |
| 853 | - 'colcycle' : simple_iterator('col_left', 'col_right'), |
| 854 | + 'colcycle': simple_iterator('col_left', 'col_right'), |
| 855 | } |
| 856 | - return render_to_response('events/global_event_detail.html', |
| 857 | + return render_to_response('events/global_event_detail.html', |
| 858 | context, RequestContext(request)) |
| 859 | |
| 860 | + |
| 861 | @login_required |
| 862 | def global_event_delete(request, global_event_id): |
| 863 | """ |
| 864 | delete a event |
| 865 | """ |
| 866 | global_event_object = get_object_or_404(GlobalEvent, pk=global_event_id) |
| 867 | - |
| 868 | + |
| 869 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 870 | - |
| 871 | + |
| 872 | if is_on_lc: |
| 873 | - if request.method == 'POST': |
| 874 | + if request.method == 'POST': |
| 875 | global_event_object.delete() |
| 876 | request.user.message_set.create(message=_('Global Event removed.')) |
| 877 | - return redirect( 'event-list' ) |
| 878 | + return redirect('event-list') |
| 879 | else: |
| 880 | context = {'global_event_object': global_event_object} |
| 881 | return render_to_response('events/global_event_delete_confirm.html', context, RequestContext(request)) |
| 882 | else: |
| 883 | request.user.message_set.create(message='%s %s' % (_('You can not remove this global event.'), _('You are not on the LoCo Council.'))) |
| 884 | - return redirect( global_event_object ) |
| 885 | + return redirect(global_event_object) |
| 886 | + |
| 887 | |
| 888 | @login_required |
| 889 | def global_event_new(request,): |
| 890 | @@ -443,23 +449,24 @@ |
| 891 | """ |
| 892 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 893 | if is_on_lc: |
| 894 | - if request.method == 'POST': |
| 895 | + if request.method == 'POST': |
| 896 | form = GlobalEventForm(data=request.POST) |
| 897 | if form.is_valid(): |
| 898 | form.save() |
| 899 | request.user.message_set.create(message=_('New Global Event created.')) |
| 900 | - return redirect( 'event-list' ) |
| 901 | + return redirect('event-list') |
| 902 | else: |
| 903 | form = GlobalEventForm() |
| 904 | - |
| 905 | + |
| 906 | context = { |
| 907 | 'form': form, |
| 908 | } |
| 909 | - return render_to_response('events/global_event_new.html', |
| 910 | + return render_to_response('events/global_event_new.html', |
| 911 | context, RequestContext(request)) |
| 912 | else: |
| 913 | request.user.message_set.create(message='%s %s' % (_('You can not add a new global event.'), _('You are not on the LoCo Council.'))) |
| 914 | - return redirect( 'event-list' ) |
| 915 | + return redirect('event-list') |
| 916 | + |
| 917 | |
| 918 | @login_required |
| 919 | def global_event_update(request, global_event_id): |
| 920 | @@ -467,26 +474,27 @@ |
| 921 | update global event |
| 922 | """ |
| 923 | global_event_object = get_object_or_404(GlobalEvent, pk=global_event_id) |
| 924 | - |
| 925 | + |
| 926 | is_on_lc = launchpad.is_user_on_loco_council(request.user) |
| 927 | if is_on_lc: |
| 928 | - if request.method == 'POST': |
| 929 | + if request.method == 'POST': |
| 930 | form = GlobalEventForm(data=request.POST, instance=global_event_object) |
| 931 | if form.is_valid(): |
| 932 | form.save() |
| 933 | request.user.message_set.create(message=_('Global Event updated.')) |
| 934 | - return redirect( global_event_object ) |
| 935 | + return redirect(global_event_object) |
| 936 | else: |
| 937 | form = GlobalEventForm(instance=global_event_object) |
| 938 | - |
| 939 | + |
| 940 | context = { |
| 941 | 'form': form, |
| 942 | } |
| 943 | - return render_to_response('events/global_event_update.html', |
| 944 | + return render_to_response('events/global_event_update.html', |
| 945 | context, RequestContext(request)) |
| 946 | else: |
| 947 | request.user.message_set.create(message='%s %s' % (_('You can not update this global event.'), _('You are not on the LoCo Council.'))) |
| 948 | - return redirect( global_event_object ) |
| 949 | + return redirect(global_event_object) |
| 950 | + |
| 951 | |
| 952 | def team_event_locations(request): |
| 953 | """ |
| 954 | @@ -501,8 +509,8 @@ |
| 955 | if event.venue is None: |
| 956 | continue |
| 957 | location['content'] = '<p>Location: <a href="%s">%s</a></p><p>Start date: %s</p><p>End date: %s</p>' % (event.get_absolute_url(), |
| 958 | - event.venue.name, |
| 959 | - str(event.date_begin), |
| 960 | + event.venue.name, |
| 961 | + str(event.date_begin), |
| 962 | str(event.date_end)) |
| 963 | location['lng'] = event.venue.longitude |
| 964 | location['lat'] = event.venue.latitude |
| 965 | @@ -511,7 +519,8 @@ |
| 966 | json = simplejson.dumps(locations) |
| 967 | |
| 968 | return HttpResponse(json) |
| 969 | - |
| 970 | + |
| 971 | + |
| 972 | def global_event_locations(request, global_event_id): |
| 973 | """ |
| 974 | the longitude and latitude global event |
| 975 | @@ -524,8 +533,8 @@ |
| 976 | location['title'] = event.name |
| 977 | # TODO: create an separate view with template for the content |
| 978 | location['content'] = '<p>Location: <a href="%s">%s</a></p><p>Start date: %s</p><p>End date: %s</p>' % (event.get_absolute_url(), |
| 979 | - event.venue.name, |
| 980 | - str(event.date_begin), |
| 981 | + event.venue.name, |
| 982 | + str(event.date_begin), |
| 983 | str(event.date_end)) |
| 984 | location['lng'] = event.venue.longitude |
| 985 | location['lat'] = event.venue.latitude |
| 986 | @@ -534,7 +543,8 @@ |
| 987 | json = simplejson.dumps(locations) |
| 988 | |
| 989 | return HttpResponse(json) |
| 990 | - |
| 991 | + |
| 992 | + |
| 993 | def global_jam(request): |
| 994 | try: |
| 995 | global_event_object = GlobalEvent.objects.filter(name='Ubuntu Global Jam').order_by('-date_begin')[0] |
| 996 | @@ -542,6 +552,7 @@ |
| 997 | raise Http404 |
| 998 | return global_event_detail(request, global_event_object.id) |
| 999 | |
| 1000 | + |
| 1001 | def global_jam_dashboard(request): |
| 1002 | try: |
| 1003 | global_event_object = GlobalEvent.objects.filter(name='Ubuntu Global Jam').order_by('-date_begin')[0] |
| 1004 | @@ -552,4 +563,3 @@ |
| 1005 | 'global_event_object': global_event_object, |
| 1006 | } |
| 1007 | return render_to_response('events/global_jam_dashboard.html', context, RequestContext(request)) |
| 1008 | - |

