kopia lustrzana https://github.com/glidernet/ogn-python
Better celery messages
rodzic
ba588f54e9
commit
0c152cac5b
14
README.md
14
README.md
|
@ -76,7 +76,19 @@ For best performance you should use [TimescaleDB](https://www.timescale.com), wh
|
||||||
```
|
```
|
||||||
raster2pgsql -s 4326 -c -C -I -M -t 100x100 elevation_data.tif public.elevation | psql -d ogn
|
raster2pgsql -s 4326 -c -C -I -M -t 100x100 elevation_data.tif public.elevation | psql -d ogn
|
||||||
```
|
```
|
||||||
|
|
||||||
|
11. Import Airports (needed for takeoff and landing calculation). A cup file is provided under tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
flask database import_airports tests/SeeYou.cup
|
||||||
|
```
|
||||||
|
|
||||||
|
12. Import DDB (needed for registration signs in the logbook).
|
||||||
|
|
||||||
|
```
|
||||||
|
flask database import_ddb
|
||||||
|
```
|
||||||
|
|
||||||
There is also a [Vagrant](https://www.vagrantup.com/) environment for the development of ogn-python.
|
There is also a [Vagrant](https://www.vagrantup.com/) environment for the development of ogn-python.
|
||||||
You can create and start this virtual machine with `vagrant up` and login with `vagrant ssh`.
|
You can create and start this virtual machine with `vagrant up` and login with `vagrant ssh`.
|
||||||
The code of ogn-python will be available in the shared folder `/vagrant`.
|
The code of ogn-python will be available in the shared folder `/vagrant`.
|
||||||
|
|
|
@ -25,7 +25,8 @@ def update_takeoff_landings(last_minutes):
|
||||||
|
|
||||||
end = datetime.datetime.utcnow()
|
end = datetime.datetime.utcnow()
|
||||||
start = end - datetime.timedelta(minutes=last_minutes)
|
start = end - datetime.timedelta(minutes=last_minutes)
|
||||||
takeoff_update_entries(session=db.session, start=start, end=end, logger=logger)
|
result = takeoff_update_entries(session=db.session, start=start, end=end, logger=logger)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name='update_logbook_entries')
|
@celery.task(name='update_logbook_entries')
|
||||||
|
@ -33,28 +34,32 @@ def update_logbook_entries():
|
||||||
"""Add/update logbook entries."""
|
"""Add/update logbook entries."""
|
||||||
|
|
||||||
today = datetime.datetime.today()
|
today = datetime.datetime.today()
|
||||||
logbook_update_entries(session=db.session, date=today, logger=logger)
|
result = logbook_update_entries(session=db.session, date=today, logger=logger)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name='update_logbook_max_altitude')
|
@celery.task(name='update_logbook_max_altitude')
|
||||||
def update_logbook_max_altitude():
|
def update_logbook_max_altitude():
|
||||||
"""Add max altitudes in logbook when flight is complete (takeoff and landing)."""
|
"""Add max altitudes in logbook when flight is complete (takeoff and landing)."""
|
||||||
|
|
||||||
logbook_update_max_altitudes(session=db.session, logger=logger)
|
result = logbook_update_max_altitudes(session=db.session, logger=logger)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name='import_ddb')
|
@celery.task(name='import_ddb')
|
||||||
def import_ddb():
|
def import_ddb():
|
||||||
"""Import registered devices from the DDB."""
|
"""Import registered devices from the DDB."""
|
||||||
|
|
||||||
device_infos_import_ddb(session=db.session, logger=logger)
|
result = device_infos_import_ddb(session=db.session, logger=logger)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name='update_receivers_country_code')
|
@celery.task(name='update_receivers_country_code')
|
||||||
def update_receivers_country_code():
|
def update_receivers_country_code():
|
||||||
"""Update country code in receivers table if None."""
|
"""Update country code in receivers table if None."""
|
||||||
|
|
||||||
receivers_update_country_code(session=db.session, logger=logger)
|
result = receivers_update_country_code(session=db.session, logger=logger)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name='purge_old_data')
|
@celery.task(name='purge_old_data')
|
||||||
|
|
|
@ -23,7 +23,7 @@ def upsert(session, model, rows, update_cols):
|
||||||
|
|
||||||
# print(compile_query(on_conflict_stmt))
|
# print(compile_query(on_conflict_stmt))
|
||||||
session.execute(on_conflict_stmt)
|
session.execute(on_conflict_stmt)
|
||||||
|
|
||||||
|
|
||||||
def update_device_infos(session, address_origin, path=None):
|
def update_device_infos(session, address_origin, path=None):
|
||||||
if address_origin == DeviceInfoOrigin.flarmnet:
|
if address_origin == DeviceInfoOrigin.flarmnet:
|
||||||
|
@ -53,9 +53,10 @@ def import_ddb(session, logger=None):
|
||||||
|
|
||||||
logger.info("Import registered devices fom the DDB...")
|
logger.info("Import registered devices fom the DDB...")
|
||||||
counter = update_device_infos(session, DeviceInfoOrigin.ogn_ddb)
|
counter = update_device_infos(session, DeviceInfoOrigin.ogn_ddb)
|
||||||
logger.info("Imported {} devices.".format(counter))
|
|
||||||
|
|
||||||
return "Imported {} devices.".format(counter)
|
finish_message = "DeviceInfo: {} inserted.".format(counter)
|
||||||
|
logger.info(finish_message)
|
||||||
|
return finish_message
|
||||||
|
|
||||||
|
|
||||||
def update_country_code(session, logger=None):
|
def update_country_code(session, logger=None):
|
||||||
|
@ -70,6 +71,7 @@ def update_country_code(session, logger=None):
|
||||||
synchronize_session='fetch')
|
synchronize_session='fetch')
|
||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
logger.info("Updated {} AircraftBeacons".format(update_receivers))
|
|
||||||
|
|
||||||
return "Updated country for {} Receivers".format(update_receivers)
|
finish_message = "Receivers (country): {} updated".format(update_receivers)
|
||||||
|
logger.info(finish_message)
|
||||||
|
return finish_message
|
||||||
|
|
|
@ -137,9 +137,10 @@ def update_entries(session, date, logger=None):
|
||||||
result = session.execute(ins)
|
result = session.execute(ins)
|
||||||
insert_counter = result.rowcount
|
insert_counter = result.rowcount
|
||||||
session.commit()
|
session.commit()
|
||||||
logger.debug("New logbook entries: {}".format(insert_counter))
|
|
||||||
|
|
||||||
return "Logbook entries: {} inserted, {} updated".format(insert_counter, update_counter)
|
finish_message = "Logbook: {} inserted, {} updated".format(insert_counter, update_counter)
|
||||||
|
logger.debug(finish_message)
|
||||||
|
return finish_message
|
||||||
|
|
||||||
|
|
||||||
def update_max_altitudes(session, logger=None):
|
def update_max_altitudes(session, logger=None):
|
||||||
|
@ -173,6 +174,7 @@ def update_max_altitudes(session, logger=None):
|
||||||
synchronize_session='fetch')
|
synchronize_session='fetch')
|
||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
logger.info("Logbook: {} entries updated.".format(update_logbook))
|
|
||||||
|
|
||||||
return "Logbook: {} entries updated.".format(update_logbook)
|
finish_message = "Logbook (altitude): {} entries updated.".format(update_logbook)
|
||||||
|
logger.info(finish_message)
|
||||||
|
return finish_message
|
||||||
|
|
|
@ -80,6 +80,7 @@ def create_receiver_coverage(session, date, logger=None):
|
||||||
result = session.execute(ins)
|
result = session.execute(ins)
|
||||||
insert_counter = result.rowcount
|
insert_counter = result.rowcount
|
||||||
session.commit()
|
session.commit()
|
||||||
logger.debug("New receiver coverage entries: {}".format(insert_counter))
|
|
||||||
|
|
||||||
return "Receiver coverage entries: {} inserted, {} updated".format(insert_counter, update_counter)
|
finish_message = "ReceiverCoverage: {} inserted, {} updated".format(insert_counter, update_counter)
|
||||||
|
logger.debug(finish_message)
|
||||||
|
return finish_message
|
||||||
|
|
|
@ -134,6 +134,7 @@ def update_entries(session, start, end, logger=None):
|
||||||
result = session.execute(ins)
|
result = session.execute(ins)
|
||||||
session.commit()
|
session.commit()
|
||||||
insert_counter = result.rowcount
|
insert_counter = result.rowcount
|
||||||
logger.info("Inserted {} TakeoffLandings".format(insert_counter))
|
|
||||||
|
|
||||||
return "Inserted {} TakeoffLandings".format(insert_counter)
|
finish_message = "TakeoffLandings: Inserted {}".format(insert_counter)
|
||||||
|
logger.info(finish_message)
|
||||||
|
return finish_message
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import datetime
|
||||||
|
|
||||||
from sqlalchemy.ext.hybrid import hybrid_property
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
|
|
||||||
from ogn_python import db
|
from ogn_python import db
|
||||||
|
@ -36,3 +38,29 @@ class Device(db.Model):
|
||||||
.order_by(DeviceInfo.address_origin)
|
.order_by(DeviceInfo.address_origin)
|
||||||
|
|
||||||
return query.first()
|
return query.first()
|
||||||
|
|
||||||
|
EXPIRY_DATES = {
|
||||||
|
6.67: datetime.date(2020, 10, 31),
|
||||||
|
6.63: datetime.date(2020, 5, 31),
|
||||||
|
6.62: datetime.date(2020, 5, 31),
|
||||||
|
6.6: datetime.date(2020, 1, 31),
|
||||||
|
6.42: datetime.date(2019, 10, 31),
|
||||||
|
6.41: datetime.date(2019, 1, 31),
|
||||||
|
6.4: datetime.date(2019, 1, 31),
|
||||||
|
6.09: datetime.date(2018, 9, 30),
|
||||||
|
6.08: datetime.date(2018, 9, 30),
|
||||||
|
6.07: datetime.date(2018, 3, 31),
|
||||||
|
6.06: datetime.date(2017, 9, 30),
|
||||||
|
6.05: datetime.date(2017, 3, 31),
|
||||||
|
}
|
||||||
|
|
||||||
|
def expiry_date(self):
|
||||||
|
if self.name.startswith('FLR'):
|
||||||
|
if self.software_version in self.EXPIRY_DATES:
|
||||||
|
return self.EXPIRY_DATES[self.software_version]
|
||||||
|
else:
|
||||||
|
return datetime.date(2000, 1, 1)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import datetime
|
||||||
|
|
||||||
from flask import request, render_template
|
from flask import request, render_template
|
||||||
from sqlalchemy import func, and_, or_
|
from sqlalchemy import func, and_, or_
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ def airports():
|
||||||
.order_by(Country.iso2)
|
.order_by(Country.iso2)
|
||||||
|
|
||||||
if sel_country:
|
if sel_country:
|
||||||
airports = db.session.query(Airport) \
|
airports = db.session.query(Airport, Receiver).outerjoin(Receiver) \
|
||||||
.filter(and_(or_(Logbook.takeoff_airport_id == Airport.id, Logbook.landing_airport_id == Airport.id), Airport.country_code == sel_country)) \
|
.filter(and_(or_(Logbook.takeoff_airport_id == Airport.id, Logbook.landing_airport_id == Airport.id), Airport.country_code == sel_country)) \
|
||||||
.group_by(Airport.id) \
|
.group_by(Airport.id) \
|
||||||
.order_by(Airport.name)
|
.order_by(Airport.name)
|
||||||
|
@ -197,10 +199,16 @@ def logbook():
|
||||||
|
|
||||||
@app.route('/statistics.html')
|
@app.route('/statistics.html')
|
||||||
def statistics():
|
def statistics():
|
||||||
receiverstats = db.session.query(ReceiverStats) \
|
|
||||||
.limit(10)
|
|
||||||
|
|
||||||
return render_template('statistics.html', receiverstats=receiverstats)
|
today = datetime.date.today()
|
||||||
|
today = datetime.date(2018, 7, 31)
|
||||||
|
|
||||||
|
receiverstats = db.session.query(ReceiverStats) \
|
||||||
|
.filter(ReceiverStats.date == today)
|
||||||
|
|
||||||
|
return render_template('statistics.html',
|
||||||
|
title='Receiver Statistics',
|
||||||
|
receiverstats=receiverstats)
|
||||||
|
|
||||||
# Backend routes for other sites
|
# Backend routes for other sites
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<td><a href="{{ url_for('device_detail', id=device.id) }}">{{ device.address }}</a></td>
|
<td><a href="{{ url_for('device_detail', id=device.id) }}">{{ device.address }}</a></td>
|
||||||
<td>{% if device.info is none %}-{% else %}{{ device.info.registration }}{% endif %}</a></td>
|
<td>{% if device.info is none %}-{% else %}{{ device.info.registration }}{% endif %}</a></td>
|
||||||
<td>{% if device.takeoff_landings %}{% set last_action = device.takeoff_landings|last %}{% if last_action.is_takeoff == True %}↗{% else %}↘{% endif %} @ {{ last_action.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}{% endif %}
|
<td>{% if device.takeoff_landings %}{% set last_action = device.takeoff_landings|last %}{% if last_action.is_takeoff == True %}↗{% else %}↘{% endif %} @ {{ last_action.timestamp.strftime('%Y-%m-%d %H:%M:%S') }}{% endif %}
|
||||||
<td>{{ device.software_version }}</td>
|
<td>{% if device.software_version is not none %}{{ device.software_version }}{% else %}-{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -55,8 +55,8 @@
|
||||||
<td>{% if entry.duration is not none %}{{ entry.duration }}{% endif %}</td>
|
<td>{% if entry.duration is not none %}{{ entry.duration }}{% endif %}</td>
|
||||||
<td>{% if entry.max_altitude is not none %}{{ '%0.1f'|format(entry.max_altitude - entry.takeoff_airport.altitude) }} m{% endif %}</td>
|
<td>{% if entry.max_altitude is not none %}{{ '%0.1f'|format(entry.max_altitude - entry.takeoff_airport.altitude) }} m{% endif %}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if entry.takeoff_airport is not none and entry.takeoff_airport.id|string() != sel_airport %}Take Off: <a href="{{ url_for('logbook', airport=entry.takeoff_airport.id) }}">{{ entry.takeoff_airport.name }}</a>
|
{% if entry.takeoff_airport is not none and entry.takeoff_airport.id|string() != sel_airport %}Take Off: <img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ entry.takeoff_airport.country_code|lower }}" alt="{{ entry.takeoff_airport.country_code }}"/> <a href="{{ url_for('logbook', airport=entry.takeoff_airport.id) }}">{{ entry.takeoff_airport.name }}</a>
|
||||||
{% elif entry.landing_airport is not none and entry.landing_airport.id|string() != sel_airport %}Landing: <a href="{{ url_for('logbook', airport=entry.landing_airport.id) }}">{{ entry.landing_airport.name }}</a>
|
{% elif entry.landing_airport is not none and entry.landing_airport.id|string() != sel_airport %}Landing: <img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ entry.landing_airport.country_code|lower }}" alt="{{ entry.landing_airport.country_code }}"/> <a href="{{ url_for('logbook', airport=entry.landing_airport.id) }}">{{ entry.landing_airport.name }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<tr><td>Name:</td><td><img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ receiver.country.iso2|lower }}" alt="{{ receiver.country.iso2 }}"/> {{ receiver.name }}</td></tr>
|
<tr><td>Name:</td><td><img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ receiver.country.iso2|lower }}" alt="{{ receiver.country.iso2 }}"/> {{ receiver.name }}</td></tr>
|
||||||
<tr><td>Airport:</td>
|
<tr><td>Airport:</td>
|
||||||
<td>{% if airport is not none %}<img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ airport.country_code|lower }}" alt="{{ airport.country_code }}"/>
|
<td>{% if airport is not none %}<img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ airport.country_code|lower }}" alt="{{ airport.country_code }}"/>
|
||||||
{% if airport.takeoff_landings %}<a href="{{ url_for('logbook', airport=airport.id) }}">{{ airport.name }}</a>{% else %}{{ airport.name }}{% endif %}
|
{% if airport.takeoff_landings %}<a href="{{ url_for('airport_detail', airport=airport.id) }}">{{ airport.name }}</a>{% else %}{{ airport.name }}{% endif %}
|
||||||
{% else %}-{% endif %}
|
{% else %}-{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -11,15 +11,13 @@
|
||||||
<table class="datatable table table-striped table-bordered">
|
<table class="datatable table table-striped table-bordered">
|
||||||
<tr>
|
<tr>
|
||||||
<th>Receiver</th>
|
<th>Receiver</th>
|
||||||
<th>Country</th>
|
|
||||||
<th>Aircrafts</th>
|
<th>Aircrafts</th>
|
||||||
<th>Beacons</th>
|
<th>Beacons</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{% for receiverstat in receiverstats %}
|
{% for receiverstat in receiverstats %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ receiverstat.receiver.name }}</td>
|
<td><img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ receiverstat.receiver.country.iso2|lower }}" alt="{{ receiverstat.receiver.country.iso2 }}"/> {{ receiverstat.receiver.name }}</td>
|
||||||
<td><img src="{{ url_for('static', filename='img/Transparent.gif') }}" class="flag flag-{{ receiverstat.receiver.country.iso2|lower }}" alt="{{ receiverstat.receiver.country.iso2 }}"/></td>
|
|
||||||
<td>{{ receiverstat.aircraft_count }}</td>
|
<td>{{ receiverstat.aircraft_count }}</td>
|
||||||
<td>{{ receiverstat.beacon_count }}</td>
|
<td>{{ receiverstat.beacon_count }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from tests.base import TestBaseDB, db
|
||||||
|
from ogn_python.model import Device, DeviceInfo
|
||||||
|
|
||||||
|
|
||||||
|
class TestStringMethods(TestBaseDB):
|
||||||
|
def test_device_info(self):
|
||||||
|
device = Device(name='FLRDD0815', address='DD0815')
|
||||||
|
device_info1 = DeviceInfo(address='DD0815', address_origin=1, registration='D-0815')
|
||||||
|
device_info2 = DeviceInfo(address='DD0815', address_origin=2, registration='15')
|
||||||
|
|
||||||
|
db.session.add(device)
|
||||||
|
db.session.add(device_info1)
|
||||||
|
db.session.add(device_info2)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
self.assertEqual(device.info, device_info1)
|
||||||
|
|
||||||
|
def test_expiry_date(self):
|
||||||
|
device = Device(name='FLRDD0815', address='DD0815', software_version=6.42)
|
||||||
|
|
||||||
|
self.assertEqual(device.expiry_date(), datetime.date(2019, 10, 31))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Ładowanie…
Reference in New Issue