Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date of flight based on localtime #2

Merged
merged 2 commits into from
Sep 15, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions assets/SQL/30-add-localtime-date-column.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
BEGIN;

ALTER TABLE flights ADD COLUMN date_local date;
UPDATE flights SET date_local = takeoff_time;
ALTER TABLE flights ALTER COLUMN date_local SET NOT NULL;

CREATE INDEX ix_flights_date_local
ON flights
USING btree
(date_local );

COMMIT;
8 changes: 8 additions & 0 deletions assets/SQL/31-import-timezones.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
curl -O http://efele.net/maps/tz/world/tz_world.zip
unzip tz_world.zip
rm tz_world.zip
cd world
shp2pgsql -D tz_world.shp > dump.sql
psql skylines -f dump.sql
cd ..
rm -r world
1 change: 1 addition & 0 deletions assets/SQL/32-reset-needs-analysis.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
UPDATE flights SET needs_analysis = TRUE;
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"geoalchemy",
"crc16",
"markdown",
"pytz",
]

if sys.version_info[:2] == (2, 4):
Expand Down
27 changes: 13 additions & 14 deletions skylines/controllers/flights.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,8 @@ def __do_list(self, tab, kw, date=None, pilot=None, club=None, airport=None, \
.options(subqueryload(Flight.comments))

if date:
flights = flights.filter(between(Flight.takeoff_time,
date, date + timedelta(days=1)))
flights = flights.filter(Flight.date_local == date)

if pilot:
flights = flights.filter(or_(Flight.pilot == pilot,
Flight.co_pilot == pilot))
Expand All @@ -388,7 +388,7 @@ def __do_list(self, tab, kw, date=None, pilot=None, club=None, airport=None, \
if request.response_type == 'application/json':
if not columns:
columns = {
0: 'takeoff_time',
0: 'date_local',
1: 'olc_plus_score',
2: 'display_name',
3: 'olc_classic_distance',
Expand All @@ -406,8 +406,8 @@ def __do_list(self, tab, kw, date=None, pilot=None, club=None, airport=None, \
for flight in flights:
aaData.append(dict(takeoff_time = flight.takeoff_time.strftime('%H:%M'),
landing_time = flight.landing_time.strftime('%H:%M'),
date = flight.takeoff_time.strftime('%d.%m.%Y'),
date_formatted = format_date(flight.takeoff_time),
date = flight.date_local.strftime('%d.%m.%Y'),
date_formatted = format_date(flight.date_local),
olc_plus_score = flight.olc_plus_score,
olc_classic_distance = flight.olc_classic_distance,
pilot_id = flight.pilot_id,
Expand All @@ -428,18 +428,17 @@ def __do_list(self, tab, kw, date=None, pilot=None, club=None, airport=None, \
return dict(response_dict, aaData = aaData)

else:
if date:
flights = flights.order_by(desc(Flight.olc_plus_score))
else:
flights = flights.order_by(desc(Flight.takeoff_time))
if not date:
flights = flights.order_by(desc(Flight.date_local))

flights_count = flights.count()
if flights_count > int(config.get('skylines.lists.server_side', 250)):
limit = int(config.get('skylines.lists.display_length', 50))
else:
limit = int(config.get('skylines.lists.server_side', 250))

flights = flights.order_by(desc(Flight.takeoff_time)).limit(limit)
flights = flights.order_by(desc(Flight.olc_plus_score))
flights = flights.limit(limit)
return dict(tab = tab, date=date, pilot=pilot, club=club, airport=airport,
flights = flights, flights_count = flights_count)

Expand Down Expand Up @@ -469,7 +468,7 @@ def all(self, **kw):
@expose('skylines.templates.flights.list')
@expose('json')
def today(self, **kw):
query = DBSession.query(func.max(Flight.takeoff_time).label('date')) \
query = DBSession.query(func.max(Flight.date_local).label('date')) \
.filter(Flight.takeoff_time < datetime.utcnow())

date = query.one().date
Expand Down Expand Up @@ -541,7 +540,7 @@ def pilot(self, id, **kw):
pilot = get_requested_record(User, id)

columns = {
0: 'takeoff_time',
0: 'date_local',
1: 'olc_plus_score',
2: 'display_name',
3: 'olc_classic_distance',
Expand All @@ -560,7 +559,7 @@ def club(self, id, **kw):
club = get_requested_record(Club, id)

columns = {
0: 'takeoff_time',
0: 'date_local',
1: 'olc_plus_score',
2: 'display_name',
3: 'olc_classic_distance',
Expand All @@ -579,7 +578,7 @@ def airport(self, id, **kw):
airport = get_requested_record(Airport, id)

columns = {
0: 'takeoff_time',
0: 'date_local',
1: 'olc_plus_score',
2: 'display_name',
3: 'olc_classic_distance',
Expand Down
2 changes: 1 addition & 1 deletion skylines/controllers/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ def get_last_year_statistics(self):
func.sum(Flight.olc_classic_distance).label('distance'),
func.sum(Flight.duration).label('duration')) \
.filter(Flight.pilot == self.user) \
.filter(Flight.takeoff_time > (date.today() - timedelta(days=365))) \
.filter(Flight.date_local > (date.today() - timedelta(days=365))) \
.first()

last_year_statistics = dict(flights = 0,
Expand Down
15 changes: 14 additions & 1 deletion skylines/lib/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from skylines import files
from tg import config
from skylines.model.geo import Location
from skylines.model import DBSession, Airport, Trace, FlightPhase
from skylines.model import DBSession, Airport, Trace, FlightPhase, TimeZone
import logging

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -148,12 +148,25 @@ def save_contests(root, flight):
save_contest(contest_name, traces, flight)


def get_takeoff_date(flight):
if flight.takeoff_location is None:
return flight.takeoff_time

timezone = TimeZone.by_location(flight.takeoff_location)
if timezone is None:
return flight.takeoff_time

return timezone.fromutc(flight.takeoff_time).date()


def save_takeoff(event, flight):
flight.takeoff_time = import_datetime_attribute(event, 'time')
flight.takeoff_location = read_location(event)
if flight.takeoff_location is not None:
flight.takeoff_airport = Airport.by_location(flight.takeoff_location)

flight.date_local = get_takeoff_date(flight)


def save_landing(event, flight):
flight.landing_time = import_datetime_attribute(event, 'time')
Expand Down
2 changes: 1 addition & 1 deletion skylines/lib/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def format_timedelta(delta):

def format_flight_title(flight):
title = format_distance(flight.olc_classic_distance)
title = title + ' on ' + format_date(flight.takeoff_time)
title = title + ' on ' + format_date(flight.date_local)

tagline = ''
if flight.pilot:
Expand Down
1 change: 1 addition & 0 deletions skylines/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ def init_model(engine):
from skylines.model.airport import Airport
from skylines.model.follower import Follower
from skylines.model.airspace import Airspace
from skylines.model.timezone import TimeZone
from skylines.model.trace import Trace
from skylines.model.notification import Notification
9 changes: 6 additions & 3 deletions skylines/model/flight.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from datetime import datetime
from sqlalchemy.orm import relation
from sqlalchemy import ForeignKey, Column, func
from sqlalchemy.types import Unicode, Integer, DateTime, Boolean
from sqlalchemy.types import Unicode, Integer, DateTime, Date, Boolean
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.sql.expression import desc
from skylines.model.auth import User
Expand Down Expand Up @@ -35,6 +35,9 @@ class Flight(DeclarativeBase):
model = relation('Model', primaryjoin=(model_id == Model.id))
registration = Column(Unicode(32))

# The date of the flight in local time instead of UTC. Used for scoring.
date_local = Column(Date, nullable=False, index=True)

takeoff_time = Column(DateTime, nullable=False, index=True)
landing_time = Column(DateTime, nullable=False)
takeoff_location_wkt = GeometryColumn('takeoff_location', Point(2),
Expand Down Expand Up @@ -66,11 +69,11 @@ def duration(self):

@hybrid_property
def year(self):
return self.takeoff_time.year
return self.date_local.year

@year.expression
def year(cls):
return func.date_part('year', cls.takeoff_time)
return func.date_part('year', cls.date_local)

@property
def takeoff_location(self):
Expand Down
31 changes: 31 additions & 0 deletions skylines/model/timezone.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from sqlalchemy import Column
from sqlalchemy.types import Integer, String
from skylines.model import DeclarativeBase, DBSession
from geoalchemy.geometry import GeometryColumn, GeometryDDL, MultiPolygon
from geoalchemy.postgis import PGComparator
from geoalchemy.functions import functions
from sqlalchemy.sql.expression import func
from pytz import timezone


class TimeZone(DeclarativeBase):
__tablename__ = 'tz_world'

id = Column('gid', Integer, autoincrement=True, primary_key=True)
tzid = Column(String(30))
the_geom = GeometryColumn(MultiPolygon, comparator=PGComparator)

def __unicode__(self):
return self.tzid

@classmethod
def by_location(cls, location):
location = func.ST_MakePoint(location.longitude, location.latitude)
filter = functions.gcontains(cls.the_geom, location)
zone = DBSession.query(cls.tzid).filter(filter).scalar()
if zone is None:
return None

return timezone(unicode(zone))

GeometryDDL(TimeZone.__table__)
4 changes: 2 additions & 2 deletions skylines/templates/flights/details-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
<table py:def="render_details_table(flight)" class="table" itemscope="" itemtype="http://schema.org/SportsEvent">
<meta itemprop="url" content="/flights/${flight.id}" />
<tbody>
<tr py:if="flight.takeoff_time">
<tr py:if="flight.date_local">
<th>Date</th>
<td>
<span py:content="h.format_date(flight.takeoff_time)">
<span py:content="h.format_date(flight.date_local)">
2012-05-21
</span>
<a href="#" class="btn btn-mini pull-right share">
Expand Down
2 changes: 1 addition & 1 deletion skylines/templates/flights/flights-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<tbody>
<tr py:for="flight in flights">
<td py:if="'date' not in omitted_columns">
<span py:if="flight.takeoff_time" title="${flight.takeoff_time.strftime('%d.%m.%Y')}" py:content="h.format_date(flight.takeoff_time)">
<span py:if="flight.date_local" title="${flight.date_local.strftime('%d.%m.%Y')}" py:content="h.format_date(flight.date_local)">
2012-05-21
</span>
</td>
Expand Down
2 changes: 1 addition & 1 deletion skylines/templates/flights/meta-tags.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
description = []
description.append(format_distance(flight.olc_classic_distance))
description.append(h.format_number(flight.olc_plus_score) + ' pt')
description.append(h.format_date(flight.takeoff_time))
description.append(h.format_date(flight.date_local))

if flight.pilot:
description.append(unicode(flight.pilot))
Expand Down
4 changes: 2 additions & 2 deletions skylines/templates/notifications/notifications-table.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@
<py:def function="render_flight_comment_notification_text(notification)">
<strong>${notification.sender}</strong> commented on your
<strong>${h.format_distance(notification.flight.olc_classic_distance)}</strong> flight on the
<strong>${h.format_date(notification.flight.takeoff_time)}</strong>.
<strong>${h.format_date(notification.flight.date_local)}</strong>.
</py:def>

<py:def function="render_flight_notification_text(notification)">
<strong>${notification.sender}</strong> uploaded a new
<strong>${h.format_distance(notification.flight.olc_classic_distance)}</strong> flight on the
<strong>${h.format_date(notification.flight.takeoff_time)}</strong>.
<strong>${h.format_date(notification.flight.date_local)}</strong>.
</py:def>

<py:def function="render_follower_notification_text(notification)">
Expand Down