diff --git a/almasaopen/filters.py b/almasaopen/filters.py index e78bc55..031cd70 100644 --- a/almasaopen/filters.py +++ b/almasaopen/filters.py @@ -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) diff --git a/almasaopen/main.py b/almasaopen/main.py index 6ca6a69..8f92c1e 100644 --- a/almasaopen/main.py +++ b/almasaopen/main.py @@ -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__': diff --git a/almasaopen/util.py b/almasaopen/util.py index 4cb81e7..33b4b1c 100644 --- a/almasaopen/util.py +++ b/almasaopen/util.py @@ -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") \ No newline at end of file + 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)