Permalink
Browse files

Better time handling and more aggressive browser caching

Closes #28
Closes #27
  • Loading branch information...
1 parent a56205f commit 56fc24ba1c7f5d5bab14b66865b46aad3ba9a01a @jacobk committed Jul 17, 2011
Showing with 63 additions and 19 deletions.
  1. +10 −10 almasaopen/filters.py
  2. +31 −8 almasaopen/main.py
  3. +22 −1 almasaopen/util.py
View
@@ -1,5 +1,7 @@
+import logging
+import datetime
+
from google.appengine.ext import webapp
-from datetime import datetime, timedelta, date
import util
@@ -13,33 +15,31 @@
def format(time):
"""Format seconds to HH:MM:SS format"""
- return str(timedelta(seconds=time))
+ return str(datetime.timedelta(seconds=time))
def formatd(indate):
"""Format datetime to just date"""
- return indate.strftime("%Y-%m-%d")
+ return util.utc_as_cet(indate).strftime("%Y-%m-%d")
def formatdv(indate):
"""Format datetime to just date"""
month_name = _SE_MONTH_NAMES.get(indate.month, "sommari")
- return indate.strftime("%d %%s %Y") % month_name
+ return util.utc_as_cet(indate).strftime("%d %%s %Y") % month_name
def formatdvsy(indate):
month_name = _SE_MONTH_NAMES.get(indate.month, "sommari")
- return indate.strftime("%d %%s") % month_name
+ return util.utc_as_cet(indate).strftime("%d %%s") % month_name
def formatt(indate):
"""Format datetime to just time"""
- return indate.strftime("%H:%M:%S")
+ return util.utc_as_cet(indate).strftime("%H:%M:%S")
def formaty(indate):
"""Format datetime to just time"""
- return indate.strftime("%Y")
+ return util.utc_as_cet(indate).strftime("%Y")
def duration_from_now(dt):
- tzinfo = util.CET()
- awareified_dt = dt.replace(tzinfo=tzinfo)
- duration = datetime.now(tz=tzinfo) - awareified_dt
+ duration = datetime.datetime.utcnow() - dt
return util.duration_to_text(duration)
View
@@ -1,13 +1,19 @@
#!/usr/bin/env python
+import calendar
+import datetime
+import email.utils
+import logging
+import os
+
from google.appengine.ext import webapp, db
-from google.appengine.ext.webapp import util, template
+from google.appengine.ext.webapp import template
+import google.appengine.ext.webapp.util
from google.appengine.api import images, users
from google.appengine.ext.webapp.util import login_required
-from datetime import datetime, timedelta
-import os
# TODO: Move vogel to vendor
import jpeg
+import util
class AlmasaError(Exception):
"""Base class for all exceptions in the almasa main module"""
@@ -47,7 +53,7 @@ class Race(db.Model):
class Comment(db.Model):
"""Datastore model for comments to a race"""
racer = db.ReferenceProperty(Racer, collection_name="comments")
- time = db.DateTimeProperty()
+ time = db.DateTimeProperty(auto_now_add=True)
comment = db.TextProperty()
ref = db.ReferenceProperty(Race, collection_name="comments")
@@ -149,14 +155,21 @@ def _extract_time(self, photo_data):
raise ValidationError("Bilderna har ej korrekt EXIF data.")
except KeyError:
raise ValidationError("Bilderna saknar tidsdata :(")
- return datetime.strptime(exif_time, "%Y:%m:%d %H:%M:%S")
+ dt = datetime.datetime.strptime(exif_time, "%Y:%m:%d %H:%M:%S")
+ return util.cet_as_utc(dt)
class BasePhotoHandler(BaseHandler):
"""Handler for getting an image from the datastore"""
def serve_photo(self, race_id, photo_type):
race = db.get(race_id)
- self.response.headers['Content-Type'] = 'image/jpeg'
+ self.response.headers.add_header("Content-Type", 'image/jpeg')
+ d = datetime.datetime.utcnow() + datetime.timedelta(days=365*10)
+ t = calendar.timegm(d.utctimetuple())
+ self.response.headers.add_header("Expires", email.utils.formatdate(t,
+ localtime=False, usegmt=True))
+ self.response.headers.add_header("Cache-Control",
+ "max-age=" + str(86400*365*10))
self.response.out.write(getattr(race, photo_type))
@@ -176,7 +189,6 @@ def post(self, *ar):
comment = Comment()
comment.racer = self.current_racer
comment.comment = self.request.get('comment')
- comment.time = datetime.now()
comment.ref = db.get(ar[0])
comment.put()
self.redirect('/races/' + ar[0])
@@ -250,6 +262,16 @@ def post(self, racer_id):
self.redirect("/myraces")
+class UTCMigrater(webapp.RequestHandler):
+ def get(self):
+ q = Race.all()
+ for race in q:
+ race.start_time = util.cet_as_utc(race.start_time)
+ race.finish_time = util.cet_as_utc(race.finish_time)
+ race.put()
+ self.response.out.write("DONE!")
+
+
def main():
webapp.template.register_template_library('filters')
@@ -264,9 +286,10 @@ def main():
('/myraces', MyRaces),
('/info', Information),
('/racers/(.*)', RacerHandler),
+ ('/convert_to_utc', UTCMigrater),
('/racers', RacersHandler)],
debug=True)
- util.run_wsgi_app(application)
+ google.appengine.ext.webapp.util.run_wsgi_app(application)
if __name__ == '__main__':
View
@@ -3,6 +3,18 @@
HOUR_SEC = 3600
MIN_SEC = 60
+class UTC(datetime.tzinfo):
+
+ ZERO = datetime.timedelta(0)
+
+ def utcoffset(self, dt):
+ return self.ZERO
+
+ def dst(self, dt):
+ return self.ZERO
+TZ_UTC = UTC()
+
+
class CET(datetime.tzinfo):
HOUR = datetime.timedelta(hours=1)
@@ -22,6 +34,7 @@ def dst(self, dt):
def tzname(self,dt):
return "CET"
+TZ_CET = CET()
def pluralize(count, singular, plural):
@@ -38,4 +51,12 @@ def duration_to_text(duration):
minutes, rest = divmod(rest, MIN_SEC)
if minutes:
return pluralize(minutes, "minut", "minuter")
- return pluralize(rest, "sekund", "sekunder")
+ return pluralize(rest, "sekund", "sekunder")
+
+
+def utc_as_cet(dt):
+ return dt.replace(tzinfo=TZ_UTC).astimezone(TZ_CET)
+
+
+def cet_as_utc(dt):
+ return dt.replace(tzinfo=TZ_CET).astimezone(TZ_UTC)

0 comments on commit 56fc24b

Please sign in to comment.