Michael Hall has proposed merging 
lp:~mhall119/loco-directory/team-events-localtime into lp:loco-directory.

Requested reviews:
  loco-directory-dev (loco-directory-dev)
Related bugs:
  #610416 Time of events is shown in UTC, not local time
  https://bugs.launchpad.net/bugs/610416


Requires a minor db schema change to add tz CharField to Venue model.
-- 
https://code.launchpad.net/~mhall119/loco-directory/team-events-localtime/+merge/41306
Your team loco-directory-dev is requested to review the proposed merge of 
lp:~mhall119/loco-directory/team-events-localtime into lp:loco-directory.
=== 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:36:54 +0000
@@ -8,6 +8,8 @@
 from venues.models import Venue
 from common.forms import RenderableMixin
 
+import pytz
+
 def validate_tag(tag):
     if tag.startswith('#'):
         tag = tag[1:]
@@ -64,6 +66,17 @@
         self.fields['venue'].choices = self.grouped_venue_list()
         from common.widgets import PopupRelatedFieldWidgetWrapper
         self.fields['venue'].widget = PopupRelatedFieldWidgetWrapper(self.fields['venue'].widget, reverse('venue-new'))
+
+        self.initial['date_begin'] = self.instance.local_date_begin
+        self.initial['date_end'] = self.instance.local_date_end
+            
+    def clean(self):
+        venue = self.cleaned_data.get('venue')
+        begin = self.cleaned_data.get('date_begin')
+        end = self.cleaned_data.get('date_end')
+        self.cleaned_data['date_begin'] = venue.fromlocaltime(begin)
+        self.cleaned_data['date_end'] = venue.fromlocaltime(end)
+        return self.cleaned_data
         
     def grouped_venue_list(self):
         """

=== 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:36:54 +0000
@@ -86,13 +86,11 @@
     """ manager for a team event """
     def next_5_events(self):
         """ a list with the next 5 events """
-# XXX: Workaround for https://bugs.launchpad.net/loco-directory/+bug/531970
-        return self.filter(date_end__gt=datetime.datetime.now()-datetime.timedelta(days=1)).order_by('date_end')[:5]
+        return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end')[:5]
 
     def next_events(self):
         """ a list with all upcoming team events """
-# XXX: Workaround for https://bugs.launchpad.net/loco-directory/+bug/531970
-        return self.filter(date_end__gt=datetime.datetime.now()-datetime.timedelta(days=1)).order_by('date_end')
+        return self.filter(date_end__gt=datetime.datetime.now()).order_by('date_end')
 
     def history_events(self):
         """ all team events in history """
@@ -114,6 +112,30 @@
     def __unicode__(self):
         return "%s %s %s" % (self.name, self.venue, self.date_begin or "")
 
+    def get_local_begin(self):
+        if self.venue:
+            return self.venue.tolocaltime(self.date_begin)
+        else:
+            return self.date_begin
+    def set_local_begin(self, local_begin):
+        if self.venue:
+            self.date_begin = self.venue.fromlocaltime(local_begin)
+        else:
+            self.date_begin = local_begin
+    local_date_begin = property(get_local_begin)
+
+    def get_local_end(self):
+        if self.venue:
+            return self.venue.tolocaltime(self.date_end)
+        else:
+            return self.date_end
+    def set_local_end(self, local_end):
+        if self.venue:
+            self.date_end = self.venue.fromlocaltime(local_end)
+        else:
+            self.date_end = local_end
+    local_date_end = property(get_local_end, set_local_end)
+    
     @models.permalink
     def get_absolute_url(self):
         return ('team-event-detail', [str(self.id)])
@@ -148,6 +170,18 @@
     commenter_profile = models.ForeignKey(UserProfile, null=True)
     comment = models.TextField(help_text=_('Comment this Event'), db_index=True)
     
+    def get_local_created(self):
+        if self.team_event.venue:
+            return self.team_event.venue.tolocaltime(self.date_created)
+        else:
+            return self.date_created
+    def set_local_created(self, local_created):
+        if self.team_event.venue:
+            self.date_created = self.team_event.venue.fromlocaltime(local_created)
+        else:
+            self.date_created = local_created
+    local_date_created = property(get_local_created, set_local_created)
+    
     def __unicode__(self):
         return "Team Event: %s . Comment: %s" % (self.team_event.name, self.comment)
     

=== 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:36:54 +0000
@@ -6,9 +6,9 @@
                 <th class="form-item-label" scope="row"><label>{% trans "When:" %}</label></th>
                 <td class="form-item-value">
                     {% ifequal global_event_object.date_begin|date global_event_object.date_end|date %}
-                        {{ global_event_object.date_begin|date:"D, d N Y H:i" }} - {{ global_event_object.date_end|date:"H:i O" }}
+                        {{ global_event_object.date_begin|date:"D, d N Y H:i" }} - {{ global_event_object.date_end|date:"H:i T"}}
                     {% else %}
-                        {{ 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" }}
+                        {{ 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"}}
                     {% endifequal %}
                 </td>
             </tr>

=== 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:36:54 +0000
@@ -6,9 +6,9 @@
         <th class="form-item-label" scope="row"><label>{% trans "When:" %}</label></th>
         <td class="form-item-value">
             {% ifequal team_event_object.date_begin|date team_event_object.date_end|date %}
-                {{ team_event_object.date_begin|date:"D, d N Y H:i" }} - {{ team_event_object.date_end|date:"H:i O" }}
+                {{ team_event_object.local_date_begin|date:"D, d N Y H:i" }} - {{ team_event_object.local_date_end|date:"H:i T (O)" }}
             {% else %}
-                {{ 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" }}
+                {{ 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)" }}
             {% endifequal %}
         </td>
     </tr>

=== 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:36:54 +0000
@@ -6,7 +6,7 @@
             <a href="{% url team-event-comment-new team_event_object.id %}#comment">{% trans "Add Comment" %}</a>
         </td>
     </tr>
-{% regroup team_event_object.teameventcomment_set.all by date_created|date:"D d M Y" as comment_list %}
+{% regroup team_event_object.teameventcomment_set.all by local_date_created|date:"D d M Y" as comment_list %}
 
 {% for comment_date in comment_list %}
     <tr>

=== 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:36:54 +0000
@@ -10,8 +10,8 @@
 {% for team_event in team_event_list %}
 <tr class="team_event_list_row {% cycle "odd" "even" %}">
 <td class="event_name"><a title="{% trans "more information about this event" %}" href="{{ team_event.get_absolute_url }}">{{ team_event.name }}</a></td>
-<td class="event_begin">{{team_event.date_begin|date}} {{ team_event.date_begin|date:"H:i T"}}</td>
-<td class="event_end">{{team_event.date_end|date}} {{ team_event.date_end|date:"H:i T"}}</td>
+<td class="event_begin">{{team_event.local_date_begin|date}} {{ team_event.local_date_begin|date:"H:i T"}}</td>
+<td class="event_end">{{team_event.local_date_end|date}} {{ team_event.local_date_end|date:"H:i T"}}</td>
 <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>
 <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>
 </tr>

=== 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:36:54 +0000
@@ -25,6 +25,12 @@
 				<td class="form-item-value">{{ venue_object.country }}</td>
 		</tr>
 		{% endif %}
+		{% if venue_object.tz %}
+		<tr>
+				<th class="form-item-label" scope="row"><label>{% trans "Timezone:" %}</label></th>
+				<td class="form-item-value">{{ venue_object.tz }}</td>
+		</tr>
+		{% endif %}
 		{% if venue_object.venue_url %}
 		<tr>
 				<th class="form-item-label" scope="row"><label>{% trans "Homepage:" %}</label></th>

=== 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:36:54 +0000
@@ -3,6 +3,8 @@
 from django.contrib.auth import models as auth_models
 # Create your models here.
 
+import pytz
+
 class UserProfile(models.Model):
     " Store profile information about a user "
 
@@ -27,6 +29,21 @@
             return "%s" % self.user.username
         except:
             return "Unknown Profile"
+
+    def get_timezone(self):
+        try:
+            return pytz.timezone(self.tz)
+        except:
+            return pytz.utc
+    timezone = property(get_timezone)
+    
+    def tolocaltime(self, dt):
+        as_utc = pytz.utc.localize(dt)
+        return as_utc.astimezone(self.timezone)
+
+    def fromlocaltime(self, dt):
+        local = self.timezone.localize(dt)
+        return local.astimezone(pytz.utc)
             
 def _getUserProfile(self):
     if not self.is_authenticated():

=== 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:36:54 +0000
@@ -0,0 +1,47 @@
+
+from south.db import db
+from django.db import models
+from venues.models import *
+
+class Migration:
+    
+    def forwards(self, orm):
+        
+        # Adding field 'Venue.tz'
+        db.add_column('venues_venue', 'tz', orm['venues.venue:tz'])
+        
+    
+    
+    def backwards(self, orm):
+        
+        # Deleting field 'Venue.tz'
+        db.delete_column('venues_venue', 'tz')
+        
+    
+    
+    models = {
+        'teams.continent': {
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.TextField', [], {'max_length': '50'})
+        },
+        'teams.country': {
+            'continents': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['teams.Continent']", 'symmetrical': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.TextField', [], {'max_length': '100'})
+        },
+        'venues.venue': {
+            'Meta': {'unique_together': "(('name', 'country', 'city'), ('longitude', 'latitude'))"},
+            'address': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
+            'city': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}),
+            'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['teams.Country']", 'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'latitude': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
+            'longitude': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}),
+            'tz': ('django.db.models.fields.CharField', [], {'default': "'UTC'", 'max_length': '32'}),
+            'venue_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
+        }
+    }
+    
+    complete_apps = ['venues']

=== 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:36:54 +0000
@@ -3,6 +3,8 @@
 from django.db.models import permalink
 
 from teams.models import Country
+import pytz
+
 
 class VenueManager(models.Manager):
     """
@@ -20,6 +22,7 @@
     address = models.CharField(help_text=_('Address with Street and Number'), max_length=150, null=True, blank=True)
     longitude = models.FloatField(help_text=_('Longitude in Degrees East'), null=True, blank=True)
     latitude = models.FloatField(help_text=_('Latitude in Degrees North'), null=True, blank=True)
+    tz = models.CharField(max_length=32, verbose_name=_('Timezone'), default='UTC', choices=[(tz, tz) for tz in pytz.all_timezones], blank=False, null=False)
     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)
     comment = models.TextField(help_text=_('Comment about the Venue'), blank=True, null=True)
     
@@ -40,5 +43,37 @@
         """ get the absolute url for the venue """
         return ('venue-detail', [self.id])
 
+    def get_timezone(self):
+        try:
+            return pytz.timezone(self.tz)
+        except:
+            return pytz.utc
+    timezone = property(get_timezone)
+    
+    def tolocaltime(self, dt):
+        as_utc = pytz.utc.localize(dt)
+        return as_utc.astimezone(self.timezone)
+    
+    def fromlocaltime(self, dt):
+        local = self.timezone.localize(dt)
+        return local.astimezone(pytz.utc)
+            
+    def save(self, *args, **kargs):
+        if self.id:
+            from events.models import TeamEvent
+            old = Venue.objects.get(id=self.id)
+            retval = super(Venue, self).save(*args, **kargs)
+            if old.tz != self.tz:
+                events = TeamEvent.objects.filter(venue=self)
+                for e in events:
+                    old_offset = old.tolocaltime(e.date_begin).utcoffset()
+                    new_offset = self.tolocaltime(e.date_begin).utcoffset()
+                    e.date_begin = e.date_begin + (old_offset - new_offset)
+                    e.date_end = e.date_end + (old_offset - new_offset)
+                    e.save()
+        else:
+            retval = super(Venue, self).save(*args, **kargs)
+        return retval
+                
 def venues_without_country():
     return Venue.objects.filter(country__isnull=True)

_______________________________________________
Mailing list: https://launchpad.net/~loco-directory-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~loco-directory-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to