Merge lp:~mhall119/loco-team-portal/team-events-localtime into lp:loco-team-portal

Proposed by Michael Hall
Status: Merged
Approved by: Michael Hall
Approved revision: 332
Merged at revision: 327
Proposed branch: lp:~mhall119/loco-team-portal/team-events-localtime
Merge into: lp:loco-team-portal
Diff against target: 338 lines (+165/-13)
11 files modified
INSTALL (+1/-1)
loco_directory/events/forms.py (+13/-0)
loco_directory/events/models.py (+38/-4)
loco_directory/templates/events/global_event_detail_basic.inc.html (+2/-2)
loco_directory/templates/events/team_event_detail_basic.inc.html (+3/-3)
loco_directory/templates/events/team_event_detail_comments.inc.html (+1/-1)
loco_directory/templates/events/team_event_list.inc.html (+2/-2)
loco_directory/templates/venues/venue_detail_basic.inc.html (+6/-0)
loco_directory/userprofiles/models.py (+17/-0)
loco_directory/venues/migrations/0005_add_venue_timezone.py (+47/-0)
loco_directory/venues/models.py (+35/-0)
To merge this branch: bzr merge lp:~mhall119/loco-team-portal/team-events-localtime
Reviewer Review Type Date Requested Status
Chris Johnston Approve
Daniel Holbach (community) Approve
Review via email: mp+41306@code.launchpad.net

Description of the change

Requires a minor db schema change to add tz CharField to Venue model.

To post a comment you must log in.
Revision history for this message
Michael Hall (mhall119) wrote :

May need python-tz installed on the server before deploying

331. By Michael Hall

Check for date difference between begin and end using localtime instead of UTC

332. By Michael Hall

Add python-tz to the list of packages to apt-get install

Revision history for this message
Daniel Holbach (dholbach) wrote :

Looks good to me.

Can somebody else try this out too? I didn't test with old data.

review: Approve
Revision history for this message
Chris Johnston (cjohnston) wrote :

It looks good to me.. Tested with events already scheduled, going back and changing the TZ of the venue, which seemed to work perfectly. Then went and created new events and new venues, which also worked well.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'INSTALL'
--- INSTALL 2010-07-01 06:27:09 +0000
+++ INSTALL 2010-11-19 13:47:33 +0000
@@ -8,7 +8,7 @@
8 - sudo -u postgres createdb -O postgres loco_directory8 - sudo -u postgres createdb -O postgres loco_directory
99
10Generally:10Generally:
11 - sudo apt-get install python-django python-launchpadlib libjs-jquery-ui python-django-openid-auth python-django-south iso-codes11 - sudo apt-get install python-django python-launchpadlib libjs-jquery-ui python-django-openid-auth python-django-south iso-codes python-tz
12 - cd loco_directory12 - cd loco_directory
13 - cp local_settings.py.sample local_settings.py13 - cp local_settings.py.sample local_settings.py
14# edit local_settings.py and set DATABASE_USER, DATABASE_PASSWORD, SECRET_KEY14# edit local_settings.py and set DATABASE_USER, DATABASE_PASSWORD, SECRET_KEY
1515
=== modified file 'loco_directory/events/forms.py'
--- loco_directory/events/forms.py 2010-10-21 16:13:05 +0000
+++ loco_directory/events/forms.py 2010-11-19 13:47:33 +0000
@@ -8,6 +8,8 @@
8from venues.models import Venue8from venues.models import Venue
9from common.forms import RenderableMixin9from common.forms import RenderableMixin
1010
11import pytz
12
11def validate_tag(tag):13def validate_tag(tag):
12 if tag.startswith('#'):14 if tag.startswith('#'):
13 tag = tag[1:]15 tag = tag[1:]
@@ -64,6 +66,17 @@
64 self.fields['venue'].choices = self.grouped_venue_list()66 self.fields['venue'].choices = self.grouped_venue_list()
65 from common.widgets import PopupRelatedFieldWidgetWrapper67 from common.widgets import PopupRelatedFieldWidgetWrapper
66 self.fields['venue'].widget = PopupRelatedFieldWidgetWrapper(self.fields['venue'].widget, reverse('venue-new'))68 self.fields['venue'].widget = PopupRelatedFieldWidgetWrapper(self.fields['venue'].widget, reverse('venue-new'))
69
70 self.initial['date_begin'] = self.instance.local_date_begin
71 self.initial['date_end'] = self.instance.local_date_end
72
73 def clean(self):
74 venue = self.cleaned_data.get('venue')
75 begin = self.cleaned_data.get('date_begin')
76 end = self.cleaned_data.get('date_end')
77 self.cleaned_data['date_begin'] = venue.fromlocaltime(begin)
78 self.cleaned_data['date_end'] = venue.fromlocaltime(end)
79 return self.cleaned_data
67 80
68 def grouped_venue_list(self):81 def grouped_venue_list(self):
69 """82 """
7083
=== modified file 'loco_directory/events/models.py'
--- loco_directory/events/models.py 2010-10-14 20:26:51 +0000
+++ loco_directory/events/models.py 2010-11-19 13:47:33 +0000
@@ -86,13 +86,11 @@
86 """ manager for a team event """86 """ manager for a team event """
87 def next_5_events(self):87 def next_5_events(self):
88 """ a list with the next 5 events """88 """ a list with the next 5 events """
89# XXX: Workaround for https://bugs.launchpad.net/loco-directory/+bug/53197089 return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end')[:5]
90 return self.filter(date_end__gt=datetime.datetime.now()-datetime.timedelta(days=1)).order_by('date_end')[:5]
9190
92 def next_events(self):91 def next_events(self):
93 """ a list with all upcoming team events """92 """ a list with all upcoming team events """
94# XXX: Workaround for https://bugs.launchpad.net/loco-directory/+bug/53197093 return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end')
95 return self.filter(date_end__gt=datetime.datetime.now()-datetime.timedelta(days=1)).order_by('date_end')
9694
97 def history_events(self):95 def history_events(self):
98 """ all team events in history """96 """ all team events in history """
@@ -114,6 +112,30 @@
114 def __unicode__(self):112 def __unicode__(self):
115 return "%s %s %s" % (self.name, self.venue, self.date_begin or "")113 return "%s %s %s" % (self.name, self.venue, self.date_begin or "")
116114
115 def get_local_begin(self):
116 if self.venue:
117 return self.venue.tolocaltime(self.date_begin)
118 else:
119 return self.date_begin
120 def set_local_begin(self, local_begin):
121 if self.venue:
122 self.date_begin = self.venue.fromlocaltime(local_begin)
123 else:
124 self.date_begin = local_begin
125 local_date_begin = property(get_local_begin)
126
127 def get_local_end(self):
128 if self.venue:
129 return self.venue.tolocaltime(self.date_end)
130 else:
131 return self.date_end
132 def set_local_end(self, local_end):
133 if self.venue:
134 self.date_end = self.venue.fromlocaltime(local_end)
135 else:
136 self.date_end = local_end
137 local_date_end = property(get_local_end, set_local_end)
138
117 @models.permalink139 @models.permalink
118 def get_absolute_url(self):140 def get_absolute_url(self):
119 return ('team-event-detail', [str(self.id)])141 return ('team-event-detail', [str(self.id)])
@@ -148,6 +170,18 @@
148 commenter_profile = models.ForeignKey(UserProfile, null=True)170 commenter_profile = models.ForeignKey(UserProfile, null=True)
149 comment = models.TextField(help_text=_('Comment this Event'), db_index=True)171 comment = models.TextField(help_text=_('Comment this Event'), db_index=True)
150 172
173 def get_local_created(self):
174 if self.team_event.venue:
175 return self.team_event.venue.tolocaltime(self.date_created)
176 else:
177 return self.date_created
178 def set_local_created(self, local_created):
179 if self.team_event.venue:
180 self.date_created = self.team_event.venue.fromlocaltime(local_created)
181 else:
182 self.date_created = local_created
183 local_date_created = property(get_local_created, set_local_created)
184
151 def __unicode__(self):185 def __unicode__(self):
152 return "Team Event: %s . Comment: %s" % (self.team_event.name, self.comment)186 return "Team Event: %s . Comment: %s" % (self.team_event.name, self.comment)
153 187
154188
=== modified file 'loco_directory/templates/events/global_event_detail_basic.inc.html'
--- loco_directory/templates/events/global_event_detail_basic.inc.html 2010-09-09 19:39:40 +0000
+++ loco_directory/templates/events/global_event_detail_basic.inc.html 2010-11-19 13:47:33 +0000
@@ -6,9 +6,9 @@
6 <th class="form-item-label" scope="row"><label>{% trans "When:" %}</label></th>6 <th class="form-item-label" scope="row"><label>{% trans "When:" %}</label></th>
7 <td class="form-item-value">7 <td class="form-item-value">
8 {% ifequal global_event_object.date_begin|date global_event_object.date_end|date %}8 {% ifequal global_event_object.date_begin|date global_event_object.date_end|date %}
9 {{ global_event_object.date_begin|date:"D, d N Y H:i" }} - {{ global_event_object.date_end|date:"H:i O" }}9 {{ global_event_object.date_begin|date:"D, d N Y H:i" }} - {{ global_event_object.date_end|date:"H:i T"}}
10 {% else %}10 {% else %}
11 {{ global_event_object.date_begin|date:"D, d N Y H:i" }} - {{ global_event_object.date_end|date:"D, d N Y H:i O" }}11 {{ global_event_object.date_begin|date:"D, d N Y H:i" }} - {{ global_event_object.date_end|date:"D, d N Y H:i T"}}
12 {% endifequal %}12 {% endifequal %}
13 </td>13 </td>
14 </tr>14 </tr>
1515
=== modified file 'loco_directory/templates/events/team_event_detail_basic.inc.html'
--- loco_directory/templates/events/team_event_detail_basic.inc.html 2010-08-17 08:48:39 +0000
+++ loco_directory/templates/events/team_event_detail_basic.inc.html 2010-11-19 13:47:33 +0000
@@ -5,10 +5,10 @@
5 <tr>5 <tr>
6 <th class="form-item-label" scope="row"><label>{% trans "When:" %}</label></th>6 <th class="form-item-label" scope="row"><label>{% trans "When:" %}</label></th>
7 <td class="form-item-value">7 <td class="form-item-value">
8 {% ifequal team_event_object.date_begin|date team_event_object.date_end|date %}8 {% ifequal team_event_object.local_date_begin|date team_event_object.local_date_end|date %}
9 {{ team_event_object.date_begin|date:"D, d N Y H:i" }} - {{ team_event_object.date_end|date:"H:i O" }}9 {{ team_event_object.local_date_begin|date:"D, d N Y H:i" }} - {{ team_event_object.local_date_end|date:"H:i T (O)" }}
10 {% else %}10 {% else %}
11 {{ team_event_object.date_begin|date:"D, d N Y H:i" }} - {{ team_event_object.date_end|date:"D, d N Y H:i O" }}11 {{ team_event_object.local_date_begin|date:"D, d N Y H:i" }} - {{ team_event_object.local_date_end|date:"D, d N Y H:i T (O)" }}
12 {% endifequal %}12 {% endifequal %}
13 </td>13 </td>
14 </tr>14 </tr>
1515
=== modified file 'loco_directory/templates/events/team_event_detail_comments.inc.html'
--- loco_directory/templates/events/team_event_detail_comments.inc.html 2010-11-12 11:26:24 +0000
+++ loco_directory/templates/events/team_event_detail_comments.inc.html 2010-11-19 13:47:33 +0000
@@ -6,7 +6,7 @@
6 <a href="{% url team-event-comment-new team_event_object.id %}#comment">{% trans "Add Comment" %}</a>6 <a href="{% url team-event-comment-new team_event_object.id %}#comment">{% trans "Add Comment" %}</a>
7 </td>7 </td>
8 </tr>8 </tr>
9{% regroup team_event_object.teameventcomment_set.all by date_created|date:"D d M Y" as comment_list %}9{% regroup team_event_object.teameventcomment_set.all by local_date_created|date:"D d M Y" as comment_list %}
1010
11{% for comment_date in comment_list %}11{% for comment_date in comment_list %}
12 <tr>12 <tr>
1313
=== modified file 'loco_directory/templates/events/team_event_list.inc.html'
--- loco_directory/templates/events/team_event_list.inc.html 2010-08-17 00:25:27 +0000
+++ loco_directory/templates/events/team_event_list.inc.html 2010-11-19 13:47:33 +0000
@@ -10,8 +10,8 @@
10{% for team_event in team_event_list %}10{% for team_event in team_event_list %}
11<tr class="team_event_list_row {% cycle "odd" "even" %}">11<tr class="team_event_list_row {% cycle "odd" "even" %}">
12<td class="event_name"><a title="{% trans "more information about this event" %}" href="{{ team_event.get_absolute_url }}">{{ team_event.name }}</a></td>12<td class="event_name"><a title="{% trans "more information about this event" %}" href="{{ team_event.get_absolute_url }}">{{ team_event.name }}</a></td>
13<td class="event_begin">{{team_event.date_begin|date}} {{ team_event.date_begin|date:"H:i T"}}</td>13<td class="event_begin">{{team_event.local_date_begin|date}} {{ team_event.local_date_begin|date:"H:i T"}}</td>
14<td class="event_end">{{team_event.date_end|date}} {{ team_event.date_end|date:"H:i T"}}</td>14<td class="event_end">{{team_event.local_date_end|date}} {{ team_event.local_date_end|date:"H:i T"}}</td>
15<td class="event_global">{% if team_event.global_event %}<a href="{{ team_event.global_event.get_absolute_url }}">{{ team_event.global_event.name}}</a>{% else %}--{% endif %}</td>15<td class="event_global">{% if team_event.global_event %}<a href="{{ team_event.global_event.get_absolute_url }}">{{ team_event.global_event.name}}</a>{% else %}--{% endif %}</td>
16<td class="event_teams">{% for team in team_event.teams.all %}<a title="{% trans "more information about this team" %}" href="{{ team.get_absolute_url }}">{{ team.name }}</a>{% if not forloop.last %}<br/>{% endif %}{% endfor %}</td>16<td class="event_teams">{% for team in team_event.teams.all %}<a title="{% trans "more information about this team" %}" href="{{ team.get_absolute_url }}">{{ team.name }}</a>{% if not forloop.last %}<br/>{% endif %}{% endfor %}</td>
17</tr>17</tr>
1818
=== modified file 'loco_directory/templates/venues/venue_detail_basic.inc.html'
--- loco_directory/templates/venues/venue_detail_basic.inc.html 2010-08-19 23:02:12 +0000
+++ loco_directory/templates/venues/venue_detail_basic.inc.html 2010-11-19 13:47:33 +0000
@@ -25,6 +25,12 @@
25 <td class="form-item-value">{{ venue_object.country }}</td>25 <td class="form-item-value">{{ venue_object.country }}</td>
26 </tr>26 </tr>
27 {% endif %}27 {% endif %}
28 {% if venue_object.tz %}
29 <tr>
30 <th class="form-item-label" scope="row"><label>{% trans "Timezone:" %}</label></th>
31 <td class="form-item-value">{{ venue_object.tz }}</td>
32 </tr>
33 {% endif %}
28 {% if venue_object.venue_url %}34 {% if venue_object.venue_url %}
29 <tr>35 <tr>
30 <th class="form-item-label" scope="row"><label>{% trans "Homepage:" %}</label></th>36 <th class="form-item-label" scope="row"><label>{% trans "Homepage:" %}</label></th>
3137
=== modified file 'loco_directory/userprofiles/models.py'
--- loco_directory/userprofiles/models.py 2010-08-28 17:43:41 +0000
+++ loco_directory/userprofiles/models.py 2010-11-19 13:47:33 +0000
@@ -3,6 +3,8 @@
3from django.contrib.auth import models as auth_models3from django.contrib.auth import models as auth_models
4# Create your models here.4# Create your models here.
55
6import pytz
7
6class UserProfile(models.Model):8class UserProfile(models.Model):
7 " Store profile information about a user "9 " Store profile information about a user "
810
@@ -27,6 +29,21 @@
27 return "%s" % self.user.username29 return "%s" % self.user.username
28 except:30 except:
29 return "Unknown Profile"31 return "Unknown Profile"
32
33 def get_timezone(self):
34 try:
35 return pytz.timezone(self.tz)
36 except:
37 return pytz.utc
38 timezone = property(get_timezone)
39
40 def tolocaltime(self, dt):
41 as_utc = pytz.utc.localize(dt)
42 return as_utc.astimezone(self.timezone)
43
44 def fromlocaltime(self, dt):
45 local = self.timezone.localize(dt)
46 return local.astimezone(pytz.utc)
30 47
31def _getUserProfile(self):48def _getUserProfile(self):
32 if not self.is_authenticated():49 if not self.is_authenticated():
3350
=== added file 'loco_directory/venues/migrations/0005_add_venue_timezone.py'
--- loco_directory/venues/migrations/0005_add_venue_timezone.py 1970-01-01 00:00:00 +0000
+++ loco_directory/venues/migrations/0005_add_venue_timezone.py 2010-11-19 13:47:33 +0000
@@ -0,0 +1,47 @@
1
2from south.db import db
3from django.db import models
4from venues.models import *
5
6class Migration:
7
8 def forwards(self, orm):
9
10 # Adding field 'Venue.tz'
11 db.add_column('venues_venue', 'tz', orm['venues.venue:tz'])
12
13
14
15 def backwards(self, orm):
16
17 # Deleting field 'Venue.tz'
18 db.delete_column('venues_venue', 'tz')
19
20
21
22 models = {
23 'teams.continent': {
24 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
25 'name': ('django.db.models.fields.TextField', [], {'max_length': '50'})
26 },
27 'teams.country': {
28 'continents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['teams.Continent']", 'symmetrical': 'False'}),
29 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
30 'name': ('django.db.models.fields.TextField', [], {'max_length': '100'})
31 },
32 'venues.venue': {
33 'Meta': {'unique_together': "(('name', 'country', 'city'), ('longitude', 'latitude'))"},
34 'address': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
35 'city': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
36 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
37 'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['teams.Country']", 'null': 'True'}),
38 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
39 'latitude': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
40 'longitude': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
41 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
42 'tz': ('django.db.models.fields.CharField', [], {'default': "'UTC'", 'max_length': '32'}),
43 'venue_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
44 }
45 }
46
47 complete_apps = ['venues']
048
=== modified file 'loco_directory/venues/models.py'
--- loco_directory/venues/models.py 2010-07-29 13:54:09 +0000
+++ loco_directory/venues/models.py 2010-11-19 13:47:33 +0000
@@ -3,6 +3,8 @@
3from django.db.models import permalink3from django.db.models import permalink
44
5from teams.models import Country5from teams.models import Country
6import pytz
7
68
7class VenueManager(models.Manager):9class VenueManager(models.Manager):
8 """10 """
@@ -20,6 +22,7 @@
20 address = models.CharField(help_text=_('Address with Street and Number'), max_length=150, null=True, blank=True)22 address = models.CharField(help_text=_('Address with Street and Number'), max_length=150, null=True, blank=True)
21 longitude = models.FloatField(help_text=_('Longitude in Degrees East'), null=True, blank=True)23 longitude = models.FloatField(help_text=_('Longitude in Degrees East'), null=True, blank=True)
22 latitude = models.FloatField(help_text=_('Latitude in Degrees North'), null=True, blank=True)24 latitude = models.FloatField(help_text=_('Latitude in Degrees North'), null=True, blank=True)
25 tz = models.CharField(max_length=32, verbose_name=_('Timezone'), default='UTC', choices=[(tz, tz) for tz in pytz.all_timezones], blank=False, null=False)
23 venue_url = models.URLField(help_text=_('URL for the Venue Homepage'), verbose_name=_('URL of the Venue'), max_length=200, verify_exists=False, blank=True, null=True)26 venue_url = models.URLField(help_text=_('URL for the Venue Homepage'), verbose_name=_('URL of the Venue'), max_length=200, verify_exists=False, blank=True, null=True)
24 comment = models.TextField(help_text=_('Comment about the Venue'), blank=True, null=True)27 comment = models.TextField(help_text=_('Comment about the Venue'), blank=True, null=True)
25 28
@@ -40,5 +43,37 @@
40 """ get the absolute url for the venue """43 """ get the absolute url for the venue """
41 return ('venue-detail', [self.id])44 return ('venue-detail', [self.id])
4245
46 def get_timezone(self):
47 try:
48 return pytz.timezone(self.tz)
49 except:
50 return pytz.utc
51 timezone = property(get_timezone)
52
53 def tolocaltime(self, dt):
54 as_utc = pytz.utc.localize(dt)
55 return as_utc.astimezone(self.timezone)
56
57 def fromlocaltime(self, dt):
58 local = self.timezone.localize(dt)
59 return local.astimezone(pytz.utc)
60
61 def save(self, *args, **kargs):
62 if self.id:
63 from events.models import TeamEvent
64 old = Venue.objects.get(id=self.id)
65 retval = super(Venue, self).save(*args, **kargs)
66 if old.tz != self.tz:
67 events = TeamEvent.objects.filter(venue=self)
68 for e in events:
69 old_offset = old.tolocaltime(e.date_begin).utcoffset()
70 new_offset = self.tolocaltime(e.date_begin).utcoffset()
71 e.date_begin = e.date_begin + (old_offset - new_offset)
72 e.date_end = e.date_end + (old_offset - new_offset)
73 e.save()
74 else:
75 retval = super(Venue, self).save(*args, **kargs)
76 return retval
77
43def venues_without_country():78def venues_without_country():
44 return Venue.objects.filter(country__isnull=True)79 return Venue.objects.filter(country__isnull=True)

Subscribers

People subscribed via source and target branches