kopia lustrzana https://github.com/glidernet/ogn-python
PEP8 violations
rodzic
b9f8e14edf
commit
b263b00f7c
|
@ -39,10 +39,12 @@ def create_app(config_name='default'):
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
def register_blueprints(app):
|
def register_blueprints(app):
|
||||||
from app.main import bp as bp_main
|
from app.main import bp as bp_main
|
||||||
app.register_blueprint(bp_main)
|
app.register_blueprint(bp_main)
|
||||||
|
|
||||||
|
|
||||||
def init_celery(app=None):
|
def init_celery(app=None):
|
||||||
app = app or create_app(os.getenv('FLASK_CONFIG') or 'default')
|
app = app or create_app(os.getenv('FLASK_CONFIG') or 'default')
|
||||||
celery.conf.broker_url = app.config['BROKER_URL']
|
celery.conf.broker_url = app.config['BROKER_URL']
|
||||||
|
|
|
@ -6,6 +6,7 @@ NOTHING = ""
|
||||||
CONTEST_RELEVANT = "AND agl < 1000"
|
CONTEST_RELEVANT = "AND agl < 1000"
|
||||||
LOW_PASS = "AND agl < 50 and ground_speed > 250"
|
LOW_PASS = "AND agl < 50 and ground_speed > 250"
|
||||||
|
|
||||||
|
|
||||||
def compute_flights(date, flight_type=0):
|
def compute_flights(date, flight_type=0):
|
||||||
if flight_type == 0:
|
if flight_type == 0:
|
||||||
filter = NOTHING
|
filter = NOTHING
|
||||||
|
@ -66,6 +67,7 @@ def compute_flights(date, flight_type=0):
|
||||||
db.session.execute(query)
|
db.session.execute(query)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
def compute_gaps(date):
|
def compute_gaps(date):
|
||||||
date_str = date.strftime("%Y-%m-%d")
|
date_str = date.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
@ -105,6 +107,7 @@ def compute_gaps(date):
|
||||||
db.session.execute(query)
|
db.session.execute(query)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from app import create_app
|
from app import create_app
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
|
@ -4,8 +4,10 @@ from flask import current_app
|
||||||
from app import redis_client
|
from app import redis_client
|
||||||
from app.gateway.message_handling import sender_position_csv_strings_to_db, receiver_position_csv_strings_to_db, receiver_status_csv_strings_to_db
|
from app.gateway.message_handling import sender_position_csv_strings_to_db, receiver_position_csv_strings_to_db, receiver_status_csv_strings_to_db
|
||||||
|
|
||||||
|
|
||||||
def transfer_from_redis_to_database():
|
def transfer_from_redis_to_database():
|
||||||
unmapping = lambda s: s[0].decode('utf-8')
|
def unmapping(string):
|
||||||
|
return string[0].decode('utf-8')
|
||||||
|
|
||||||
receiver_status_data = list(map(unmapping, redis_client.zpopmin('receiver_status', 100000)))
|
receiver_status_data = list(map(unmapping, redis_client.zpopmin('receiver_status', 100000)))
|
||||||
receiver_position_data = list(map(unmapping, redis_client.zpopmin('receiver_position', 100000)))
|
receiver_position_data = list(map(unmapping, redis_client.zpopmin('receiver_position', 100000)))
|
||||||
|
|
|
@ -131,7 +131,7 @@ def update_takeoff_landings(start, end):
|
||||||
# ... add the country
|
# ... add the country
|
||||||
takeoff_landing_query = (
|
takeoff_landing_query = (
|
||||||
db.session.query(sq6.c.timestamp, sq6.c.track, sq6.c.is_takeoff, sq6.c.sender_id, sq6.c.airport_id, Country.gid)
|
db.session.query(sq6.c.timestamp, sq6.c.track, sq6.c.is_takeoff, sq6.c.sender_id, sq6.c.airport_id, Country.gid)
|
||||||
.join(Country, sq6.c.country_code==Country.iso2, isouter=True)
|
.join(Country, sq6.c.country_code == Country.iso2, isouter=True)
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ def update_logbook(offset_days=None):
|
||||||
|
|
||||||
# limit time range to given date and set window partition and window order
|
# limit time range to given date and set window partition and window order
|
||||||
if offset_days:
|
if offset_days:
|
||||||
(start, end) = date_to_timestamps(datetime.utcnow()-timedelta(days=offset_days))
|
(start, end) = date_to_timestamps(datetime.utcnow() - timedelta(days=offset_days))
|
||||||
else:
|
else:
|
||||||
(start, end) = date_to_timestamps(datetime.utcnow().date())
|
(start, end) = date_to_timestamps(datetime.utcnow().date())
|
||||||
pa = TakeoffLanding.sender_id
|
pa = TakeoffLanding.sender_id
|
||||||
|
@ -181,7 +181,6 @@ def update_logbook(offset_days=None):
|
||||||
db.func.lag(TakeoffLanding.airport_id).over(partition_by=pa, order_by=wo).label("airport_id_prev"),
|
db.func.lag(TakeoffLanding.airport_id).over(partition_by=pa, order_by=wo).label("airport_id_prev"),
|
||||||
db.func.lead(TakeoffLanding.airport_id).over(partition_by=pa, order_by=wo).label("airport_id_next")
|
db.func.lead(TakeoffLanding.airport_id).over(partition_by=pa, order_by=wo).label("airport_id_next")
|
||||||
)
|
)
|
||||||
#.filter(between(TakeoffLanding.timestamp, start, end))
|
|
||||||
.subquery()
|
.subquery()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -195,7 +194,7 @@ def update_logbook(offset_days=None):
|
||||||
)
|
)
|
||||||
.filter(sq.c.is_takeoff == db.true())
|
.filter(sq.c.is_takeoff == db.true())
|
||||||
.filter(db.or_(sq.c.is_takeoff_next == db.true(), sq.c.is_takeoff_next == db.null()))
|
.filter(db.or_(sq.c.is_takeoff_next == db.true(), sq.c.is_takeoff_next == db.null()))
|
||||||
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id==sq.c.sender_id, Logbook.takeoff_timestamp==sq.c.timestamp, Logbook.takeoff_airport_id==sq.c.airport_id)).exists())
|
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id == sq.c.sender_id, Logbook.takeoff_timestamp == sq.c.timestamp, Logbook.takeoff_airport_id == sq.c.airport_id)).exists())
|
||||||
)
|
)
|
||||||
ins = insert(Logbook).from_select(
|
ins = insert(Logbook).from_select(
|
||||||
(
|
(
|
||||||
|
@ -220,7 +219,7 @@ def update_logbook(offset_days=None):
|
||||||
)
|
)
|
||||||
.filter(db.or_(sq.c.is_takeoff_prev == db.false(), sq.c.is_takeoff_prev == db.null()))
|
.filter(db.or_(sq.c.is_takeoff_prev == db.false(), sq.c.is_takeoff_prev == db.null()))
|
||||||
.filter(sq.c.is_takeoff == db.false())
|
.filter(sq.c.is_takeoff == db.false())
|
||||||
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id==sq.c.sender_id, Logbook.landing_timestamp==sq.c.timestamp, Logbook.landing_airport_id==sq.c.airport_id)).exists())
|
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id == sq.c.sender_id, Logbook.landing_timestamp == sq.c.timestamp, Logbook.landing_airport_id == sq.c.airport_id)).exists())
|
||||||
)
|
)
|
||||||
ins = insert(Logbook).from_select(
|
ins = insert(Logbook).from_select(
|
||||||
(
|
(
|
||||||
|
@ -253,9 +252,9 @@ def update_logbook(offset_days=None):
|
||||||
|
|
||||||
# insert (new) flights
|
# insert (new) flights
|
||||||
new_flights_query = (
|
new_flights_query = (
|
||||||
db.session.query(complete_flight_query) \
|
db.session.query(complete_flight_query)
|
||||||
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id==complete_flight_query.c.sender_id, Logbook.landing_timestamp==complete_flight_query.c.landing_timestamp, Logbook.landing_airport_id==complete_flight_query.c.landing_airport_id)).exists())
|
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id == complete_flight_query.c.sender_id, Logbook.landing_timestamp == complete_flight_query.c.landing_timestamp, Logbook.landing_airport_id == complete_flight_query.c.landing_airport_id)).exists())
|
||||||
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id==complete_flight_query.c.sender_id, Logbook.takeoff_timestamp==complete_flight_query.c.takeoff_timestamp, Logbook.takeoff_airport_id==complete_flight_query.c.takeoff_airport_id)).exists())
|
.filter(~Logbook.query.filter(db.and_(Logbook.sender_id == complete_flight_query.c.sender_id, Logbook.takeoff_timestamp == complete_flight_query.c.takeoff_timestamp, Logbook.takeoff_airport_id == complete_flight_query.c.takeoff_airport_id)).exists())
|
||||||
)
|
)
|
||||||
ins = insert(Logbook).from_select(
|
ins = insert(Logbook).from_select(
|
||||||
(
|
(
|
||||||
|
@ -276,17 +275,16 @@ def update_logbook(offset_days=None):
|
||||||
# update existing landing with takeoff from complete flight
|
# update existing landing with takeoff from complete flight
|
||||||
upd = db.update(Logbook) \
|
upd = db.update(Logbook) \
|
||||||
.where(db.and_(
|
.where(db.and_(
|
||||||
Logbook.sender_id==complete_flight_query.c.sender_id,
|
Logbook.sender_id == complete_flight_query.c.sender_id,
|
||||||
Logbook.takeoff_timestamp==db.null(),
|
Logbook.takeoff_timestamp == db.null(),
|
||||||
Logbook.takeoff_airport_id==db.null(),
|
Logbook.takeoff_airport_id == db.null(),
|
||||||
Logbook.landing_timestamp!=db.null(),
|
Logbook.landing_timestamp != db.null(),
|
||||||
Logbook.landing_timestamp==complete_flight_query.c.landing_timestamp,
|
Logbook.landing_timestamp == complete_flight_query.c.landing_timestamp,
|
||||||
Logbook.landing_airport_id==complete_flight_query.c.landing_airport_id
|
Logbook.landing_airport_id == complete_flight_query.c.landing_airport_id
|
||||||
)) \
|
)) \
|
||||||
.values(takeoff_timestamp=complete_flight_query.c.takeoff_timestamp,
|
.values(takeoff_timestamp=complete_flight_query.c.takeoff_timestamp,
|
||||||
takeoff_track=complete_flight_query.c.takeoff_track,
|
takeoff_track=complete_flight_query.c.takeoff_track,
|
||||||
takeoff_airport_id=complete_flight_query.c.takeoff_airport_id
|
takeoff_airport_id=complete_flight_query.c.takeoff_airport_id)
|
||||||
)
|
|
||||||
result = db.session.execute(upd)
|
result = db.session.execute(upd)
|
||||||
current_app.logger.debug(f"Updated {result.rowcount} takeoffs to complete flights")
|
current_app.logger.debug(f"Updated {result.rowcount} takeoffs to complete flights")
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -294,17 +292,16 @@ def update_logbook(offset_days=None):
|
||||||
# update existing takeoff with landing from complete flight
|
# update existing takeoff with landing from complete flight
|
||||||
upd = db.update(Logbook) \
|
upd = db.update(Logbook) \
|
||||||
.where(db.and_(
|
.where(db.and_(
|
||||||
Logbook.sender_id==complete_flight_query.c.sender_id,
|
Logbook.sender_id == complete_flight_query.c.sender_id,
|
||||||
Logbook.takeoff_timestamp!=db.null(),
|
Logbook.takeoff_timestamp != db.null(),
|
||||||
Logbook.takeoff_timestamp==complete_flight_query.c.takeoff_timestamp,
|
Logbook.takeoff_timestamp == complete_flight_query.c.takeoff_timestamp,
|
||||||
Logbook.takeoff_airport_id==complete_flight_query.c.takeoff_airport_id,
|
Logbook.takeoff_airport_id == complete_flight_query.c.takeoff_airport_id,
|
||||||
Logbook.landing_timestamp==db.null(),
|
Logbook.landing_timestamp == db.null(),
|
||||||
Logbook.landing_airport_id==db.null()
|
Logbook.landing_airport_id == db.null()
|
||||||
)) \
|
)) \
|
||||||
.values(landing_timestamp=complete_flight_query.c.landing_timestamp,
|
.values(landing_timestamp=complete_flight_query.c.landing_timestamp,
|
||||||
landing_track=complete_flight_query.c.landing_track,
|
landing_track=complete_flight_query.c.landing_track,
|
||||||
landing_airport_id=complete_flight_query.c.landing_airport_id
|
landing_airport_id=complete_flight_query.c.landing_airport_id)
|
||||||
)
|
|
||||||
result = db.session.execute(upd)
|
result = db.session.execute(upd)
|
||||||
current_app.logger.debug(f"Updated {result.rowcount} landings to complete flights")
|
current_app.logger.debug(f"Updated {result.rowcount} landings to complete flights")
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -312,11 +309,10 @@ def update_logbook(offset_days=None):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def update_max_altitudes():
|
def update_max_altitudes():
|
||||||
MAX_UPDATES = 60
|
MAX_UPDATES = 60
|
||||||
|
|
||||||
query = f"""
|
query = """
|
||||||
UPDATE logbooks
|
UPDATE logbooks
|
||||||
SET max_altitude = sq2.max_altitude
|
SET max_altitude = sq2.max_altitude
|
||||||
FROM (
|
FROM (
|
||||||
|
@ -347,6 +343,7 @@ def update_max_altitudes():
|
||||||
|
|
||||||
return update_counter
|
return update_counter
|
||||||
|
|
||||||
|
|
||||||
def update_max_altitudes_orm():
|
def update_max_altitudes_orm():
|
||||||
"""Add max altitudes in logbook when flight is complete (takeoff and landing)."""
|
"""Add max altitudes in logbook when flight is complete (takeoff and landing)."""
|
||||||
|
|
||||||
|
@ -374,11 +371,12 @@ def update_max_altitudes_orm():
|
||||||
finish_message = "Logbook (altitude): {} entries updated.".format(update_logbooks)
|
finish_message = "Logbook (altitude): {} entries updated.".format(update_logbooks)
|
||||||
return finish_message
|
return finish_message
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from app import create_app
|
from app import create_app
|
||||||
app = create_app()
|
app = create_app()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
#result = update_takeoff_landings(start=datetime(2020, 11, 9, 10, 0, 0), end=datetime(2020, 11, 9, 15, 30, 0))
|
result = update_takeoff_landings(start=datetime(2020, 11, 9, 10, 0, 0), end=datetime(2020, 11, 9, 15, 30, 0))
|
||||||
#result = update_logbook()
|
result = update_logbook()
|
||||||
result = update_max_altitudes_orm()
|
result = update_max_altitudes_orm()
|
||||||
print(result)
|
print(result)
|
||||||
|
|
|
@ -3,8 +3,9 @@ from app.utils import get_sql_trustworthy
|
||||||
|
|
||||||
SQL_TRUSTWORTHY = get_sql_trustworthy(source_table_alias='sp')
|
SQL_TRUSTWORTHY = get_sql_trustworthy(source_table_alias='sp')
|
||||||
|
|
||||||
|
|
||||||
def create_views():
|
def create_views():
|
||||||
db.session.execute(f"""
|
db.session.execute("""
|
||||||
DROP VIEW IF EXISTS receiver_ranking CASCADE;
|
DROP VIEW IF EXISTS receiver_ranking CASCADE;
|
||||||
|
|
||||||
CREATE VIEW receiver_ranking AS
|
CREATE VIEW receiver_ranking AS
|
||||||
|
@ -23,7 +24,7 @@ def create_views():
|
||||||
ORDER BY max_distance DESC;
|
ORDER BY max_distance DESC;
|
||||||
""")
|
""")
|
||||||
|
|
||||||
db.session.execute(f"""
|
db.session.execute("""
|
||||||
DROP VIEW IF EXISTS sender_ranking CASCADE;
|
DROP VIEW IF EXISTS sender_ranking CASCADE;
|
||||||
|
|
||||||
CREATE VIEW sender_ranking AS
|
CREATE VIEW sender_ranking AS
|
||||||
|
@ -44,6 +45,7 @@ def create_views():
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
def create_timescaledb_views():
|
def create_timescaledb_views():
|
||||||
# 1. Since the reference_timestamps are strictly increasing we can set
|
# 1. Since the reference_timestamps are strictly increasing we can set
|
||||||
# the parameter 'refresh_lag' to a very short time so the materialization
|
# the parameter 'refresh_lag' to a very short time so the materialization
|
||||||
|
@ -51,7 +53,7 @@ def create_timescaledb_views():
|
||||||
# 2. The feature realtime aggregation from TimescaleDB is quite time consuming.
|
# 2. The feature realtime aggregation from TimescaleDB is quite time consuming.
|
||||||
# So we set materialized_only=true
|
# So we set materialized_only=true
|
||||||
|
|
||||||
### Sender statistics
|
# --- Sender statistics ---
|
||||||
# These stats will be used in the daily ranking, so we make the bucket < 1d
|
# These stats will be used in the daily ranking, so we make the bucket < 1d
|
||||||
db.session.execute(f"""
|
db.session.execute(f"""
|
||||||
DROP VIEW IF EXISTS sender_stats_1h CASCADE;
|
DROP VIEW IF EXISTS sender_stats_1h CASCADE;
|
||||||
|
@ -90,7 +92,7 @@ def create_timescaledb_views():
|
||||||
GROUP BY bucket, sp.name, is_trustworthy;
|
GROUP BY bucket, sp.name, is_trustworthy;
|
||||||
""")
|
""")
|
||||||
|
|
||||||
### Receiver statistics
|
# --- Receiver statistics ---
|
||||||
# These stats will be used in the daily ranking, so we make the bucket < 1d
|
# These stats will be used in the daily ranking, so we make the bucket < 1d
|
||||||
db.session.execute(f"""
|
db.session.execute(f"""
|
||||||
DROP VIEW IF EXISTS receiver_stats_1h CASCADE;
|
DROP VIEW IF EXISTS receiver_stats_1h CASCADE;
|
||||||
|
@ -129,7 +131,7 @@ def create_timescaledb_views():
|
||||||
GROUP BY bucket, sp.receiver_name, is_trustworthy;
|
GROUP BY bucket, sp.receiver_name, is_trustworthy;
|
||||||
""")
|
""")
|
||||||
|
|
||||||
### Relation statistics (sender <-> receiver)
|
# --- Relation statistics (sender <-> receiver) ---
|
||||||
# these stats will be used on a >= 1d basis, so we make the bucket = 1d
|
# these stats will be used on a >= 1d basis, so we make the bucket = 1d
|
||||||
db.session.execute(f"""
|
db.session.execute(f"""
|
||||||
DROP VIEW IF EXISTS relation_stats_1d CASCADE;
|
DROP VIEW IF EXISTS relation_stats_1d CASCADE;
|
||||||
|
|
|
@ -119,6 +119,7 @@ def import_airports(path="tests/SeeYou.cup"):
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
print("Imported {} airports.".format(len(airports)))
|
print("Imported {} airports.".format(len(airports)))
|
||||||
|
|
||||||
|
|
||||||
@user_cli.command("create_timescaledb_views")
|
@user_cli.command("create_timescaledb_views")
|
||||||
def cmd_create_timescaledb_views():
|
def cmd_create_timescaledb_views():
|
||||||
"""Create TimescaleDB views."""
|
"""Create TimescaleDB views."""
|
||||||
|
@ -126,11 +127,10 @@ def cmd_create_timescaledb_views():
|
||||||
create_timescaledb_views()
|
create_timescaledb_views()
|
||||||
print("Done")
|
print("Done")
|
||||||
|
|
||||||
|
|
||||||
@user_cli.command("create_views")
|
@user_cli.command("create_views")
|
||||||
def cmd_create_views():
|
def cmd_create_views():
|
||||||
"""Create views."""
|
"""Create views."""
|
||||||
|
|
||||||
create_views()
|
create_views()
|
||||||
print("Done")
|
print("Done")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ from app import db
|
||||||
user_cli = AppGroup("export")
|
user_cli = AppGroup("export")
|
||||||
user_cli.help = "Export data in several file formats."
|
user_cli.help = "Export data in several file formats."
|
||||||
|
|
||||||
|
|
||||||
@user_cli.command("debug_sql")
|
@user_cli.command("debug_sql")
|
||||||
@click.argument("start")
|
@click.argument("start")
|
||||||
@click.argument("end")
|
@click.argument("end")
|
||||||
|
@ -70,12 +71,11 @@ def debug_sql(start, end, name):
|
||||||
|
|
||||||
# Last: write all into file
|
# Last: write all into file
|
||||||
with open(f'{start}_{end}_{name}.sql', 'w') as file:
|
with open(f'{start}_{end}_{name}.sql', 'w') as file:
|
||||||
file.write(f'/*\n')
|
file.write('/*\n')
|
||||||
file.write(f'OGN Python SQL Export\n')
|
file.write('OGN Python SQL Export\n')
|
||||||
file.write(f'Created by: {os.getlogin()}\n')
|
file.write(f'Created by: {os.getlogin()}\n')
|
||||||
file.write(f'Created at: {datetime.datetime.utcnow()}\n')
|
file.write(f'Created at: {datetime.datetime.utcnow()}\n')
|
||||||
file.write(f'*/\n\n')
|
file.write('*/\n\n')
|
||||||
|
|
||||||
|
|
||||||
file.write("INSERT INTO airports(name, location, altitude, style, border) VALUES\n")
|
file.write("INSERT INTO airports(name, location, altitude, style, border) VALUES\n")
|
||||||
file.write(',\n'.join(airport_values) + ';\n\n')
|
file.write(',\n'.join(airport_values) + ';\n\n')
|
||||||
|
@ -139,7 +139,7 @@ def igc(address, date):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sender = db.session.query(Sender).filter(Sender.address==address).one()
|
sender = db.session.query(Sender).filter(Sender.address == address).one()
|
||||||
except NoResultFound as e:
|
except NoResultFound as e:
|
||||||
print(f"No data for '{address}' in the DB")
|
print(f"No data for '{address}' in the DB")
|
||||||
return
|
return
|
||||||
|
|
|
@ -101,36 +101,3 @@ def printout(aprs_filter):
|
||||||
current_app.logger.warning("\nStop ogn gateway")
|
current_app.logger.warning("\nStop ogn gateway")
|
||||||
|
|
||||||
client.disconnect()
|
client.disconnect()
|
||||||
|
|
||||||
@user_cli.command("convert")
|
|
||||||
@click.argument("path")
|
|
||||||
def file_import(path):
|
|
||||||
"""Convert APRS logfiles into csv files for fast bulk import."""
|
|
||||||
|
|
||||||
for (root, dirs, files) in os.walk(path):
|
|
||||||
for file in sorted(files):
|
|
||||||
print(file)
|
|
||||||
convert(os.path.join(root, file))
|
|
||||||
|
|
||||||
|
|
||||||
@user_cli.command("calculate")
|
|
||||||
@click.argument("path")
|
|
||||||
def file_calculate(path):
|
|
||||||
"""Import csv files, calculate geographic features (distance, radial, agl, ...) and make data distinct."""
|
|
||||||
|
|
||||||
file_tuples = []
|
|
||||||
for (root, dirs, files) in os.walk(path):
|
|
||||||
for file in sorted(files):
|
|
||||||
if file.startswith('aircraft_beacons') and file.endswith('.csv.gz'):
|
|
||||||
ab_filename = os.path.join(root, file)
|
|
||||||
rb_filename = os.path.join(root, 'receiver' + file[8:])
|
|
||||||
target_filename = os.path.join(root, file + '2')
|
|
||||||
if os.path.isfile(target_filename):
|
|
||||||
print("Outputfile {} already exists. Skipping".format(target_filename))
|
|
||||||
else:
|
|
||||||
file_tuples.append((ab_filename, rb_filename, target_filename))
|
|
||||||
|
|
||||||
pbar = tqdm(file_tuples)
|
|
||||||
for file_tuple in pbar:
|
|
||||||
pbar.set_description("Converting {}".format(file_tuple[0]))
|
|
||||||
calculate(file_tuple[0], file_tuple[1], file_tuple[2])
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ def aprs_string_to_message(aprs_string):
|
||||||
bearing = int(message['bearing'])
|
bearing = int(message['bearing'])
|
||||||
message['bearing'] = bearing if bearing < 360 else 0
|
message['bearing'] = bearing if bearing < 360 else 0
|
||||||
|
|
||||||
|
|
||||||
if "aircraft_type" in message:
|
if "aircraft_type" in message:
|
||||||
message["aircraft_type"] = AircraftType(message["aircraft_type"]) if message["aircraft_type"] in AircraftType.list() else AircraftType.UNKNOWN
|
message["aircraft_type"] = AircraftType(message["aircraft_type"]) if message["aircraft_type"] in AircraftType.list() else AircraftType.UNKNOWN
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ def sender_position_message_to_csv_string(message, none_character=''):
|
||||||
message['ground_speed'] if 'ground_speed' in message and message['ground_speed'] else none_character,
|
message['ground_speed'] if 'ground_speed' in message and message['ground_speed'] else none_character,
|
||||||
int(message['altitude']) if message['altitude'] else none_character,
|
int(message['altitude']) if message['altitude'] else none_character,
|
||||||
|
|
||||||
message['address_type'] if 'address_type' in message and message['address_type'] else none_character, #10
|
message['address_type'] if 'address_type' in message and message['address_type'] else none_character, # 10
|
||||||
message['aircraft_type'].name if 'aircraft_type' in message and message['aircraft_type'] else AircraftType.UNKNOWN.name,
|
message['aircraft_type'].name if 'aircraft_type' in message and message['aircraft_type'] else AircraftType.UNKNOWN.name,
|
||||||
message['stealth'] if 'stealth' in message and message['stealth'] else none_character,
|
message['stealth'] if 'stealth' in message and message['stealth'] else none_character,
|
||||||
message['address'] if 'address' in message and message['address'] else none_character,
|
message['address'] if 'address' in message and message['address'] else none_character,
|
||||||
|
@ -112,7 +112,7 @@ def sender_position_message_to_csv_string(message, none_character=''):
|
||||||
message['error_count'] if 'error_count' in message and message['error_count'] else none_character,
|
message['error_count'] if 'error_count' in message and message['error_count'] else none_character,
|
||||||
message['frequency_offset'] if 'frequency_offset' in message and message['frequency_offset'] else none_character,
|
message['frequency_offset'] if 'frequency_offset' in message and message['frequency_offset'] else none_character,
|
||||||
message['gps_quality_horizontal'] if 'gps_quality_horizontal' in message and message['gps_quality_horizontal'] else none_character,
|
message['gps_quality_horizontal'] if 'gps_quality_horizontal' in message and message['gps_quality_horizontal'] else none_character,
|
||||||
message['gps_quality_vertical'] if 'gps_quality_vertical' in message and message['gps_quality_vertical'] else none_character, #20
|
message['gps_quality_vertical'] if 'gps_quality_vertical' in message and message['gps_quality_vertical'] else none_character, # 20
|
||||||
message['software_version'] if 'software_version' in message and message['software_version'] else none_character,
|
message['software_version'] if 'software_version' in message and message['software_version'] else none_character,
|
||||||
message['hardware_version'] if 'hardware_version' in message and message['hardware_version'] else none_character,
|
message['hardware_version'] if 'hardware_version' in message and message['hardware_version'] else none_character,
|
||||||
message['real_address'] if 'real_address' in message and message['real_address'] else none_character,
|
message['real_address'] if 'real_address' in message and message['real_address'] else none_character,
|
||||||
|
@ -238,7 +238,7 @@ def sender_position_csv_strings_to_db(lines):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Update sender_infos FK -> senders
|
# Update sender_infos FK -> senders
|
||||||
cursor.execute(f"""
|
cursor.execute("""
|
||||||
UPDATE sender_infos AS si
|
UPDATE sender_infos AS si
|
||||||
SET sender_id = s.id
|
SET sender_id = s.id
|
||||||
FROM senders AS s
|
FROM senders AS s
|
||||||
|
@ -340,7 +340,7 @@ def receiver_position_csv_strings_to_db(lines):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Update receiver country
|
# Update receiver country
|
||||||
cursor.execute(f"""
|
cursor.execute("""
|
||||||
UPDATE receivers AS r
|
UPDATE receivers AS r
|
||||||
SET
|
SET
|
||||||
country_id = c.gid
|
country_id = c.gid
|
||||||
|
@ -349,7 +349,7 @@ def receiver_position_csv_strings_to_db(lines):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
# Update receiver airport
|
# Update receiver airport
|
||||||
cursor.execute(f"""
|
cursor.execute("""
|
||||||
UPDATE receivers AS r
|
UPDATE receivers AS r
|
||||||
SET
|
SET
|
||||||
airport_id = (
|
airport_id = (
|
||||||
|
|
|
@ -37,6 +37,7 @@ class Timer(object):
|
||||||
print("[{}]".format(self.name))
|
print("[{}]".format(self.name))
|
||||||
print("Elapsed: {}".format(time.time() - self.tstart))
|
print("Elapsed: {}".format(time.time() - self.tstart))
|
||||||
|
|
||||||
|
|
||||||
def export_to_path(path):
|
def export_to_path(path):
|
||||||
connection = db.engine.raw_connection()
|
connection = db.engine.raw_connection()
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import time
|
||||||
import datetime
|
import datetime
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
@bp.app_template_filter()
|
@bp.app_template_filter()
|
||||||
def timestamp_to_status(timestamp):
|
def timestamp_to_status(timestamp):
|
||||||
if datetime.datetime.utcnow() - timestamp < datetime.timedelta(minutes=10):
|
if datetime.datetime.utcnow() - timestamp < datetime.timedelta(minutes=10):
|
||||||
|
@ -15,6 +16,7 @@ def timestamp_to_status(timestamp):
|
||||||
else:
|
else:
|
||||||
return '<b>OFFLINE</b>'
|
return '<b>OFFLINE</b>'
|
||||||
|
|
||||||
|
|
||||||
@bp.app_template_filter()
|
@bp.app_template_filter()
|
||||||
def to_html_link(obj):
|
def to_html_link(obj):
|
||||||
if isinstance(obj, Airport):
|
if isinstance(obj, Airport):
|
||||||
|
@ -40,6 +42,7 @@ def to_html_link(obj):
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError("cant apply filter 'to_html_link' to object {type(obj)}")
|
raise NotImplementedError("cant apply filter 'to_html_link' to object {type(obj)}")
|
||||||
|
|
||||||
|
|
||||||
@bp.app_template_filter()
|
@bp.app_template_filter()
|
||||||
def to_ordinal(rad):
|
def to_ordinal(rad):
|
||||||
deg = math.degrees(rad)
|
deg = math.degrees(rad)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from app import db
|
from app import db
|
||||||
from app.model import *
|
from app.model import SenderDirectionStatistic
|
||||||
import random
|
import random
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from matplotlib.figure import Figure
|
from matplotlib.figure import Figure
|
||||||
|
|
||||||
|
|
||||||
def create_range_figure2(sender_id):
|
def create_range_figure2(sender_id):
|
||||||
fig = Figure()
|
fig = Figure()
|
||||||
axis = fig.add_subplot(1, 1, 1)
|
axis = fig.add_subplot(1, 1, 1)
|
||||||
|
@ -14,6 +15,7 @@ def create_range_figure2(sender_id):
|
||||||
|
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
|
|
||||||
def create_range_figure(sender_id):
|
def create_range_figure(sender_id):
|
||||||
sds = db.session.query(SenderDirectionStatistic) \
|
sds = db.session.query(SenderDirectionStatistic) \
|
||||||
.filter(SenderDirectionStatistic.sender_id == sender_id) \
|
.filter(SenderDirectionStatistic.sender_id == sender_id) \
|
||||||
|
@ -24,11 +26,11 @@ def create_range_figure(sender_id):
|
||||||
fig = Figure()
|
fig = Figure()
|
||||||
|
|
||||||
direction_data = sds.direction_data
|
direction_data = sds.direction_data
|
||||||
max_range = max([r['max_range']/1000.0 for r in direction_data])
|
max_range = max([r['max_range'] / 1000.0 for r in direction_data])
|
||||||
|
|
||||||
theta = np.array([i['direction']/180*np.pi for i in direction_data])
|
theta = np.array([i['direction'] / 180 * np.pi for i in direction_data])
|
||||||
radii = np.array([i['max_range']/1000 if i['max_range'] > 0 else 0 for i in direction_data])
|
radii = np.array([i['max_range'] / 1000 if i['max_range'] > 0 else 0 for i in direction_data])
|
||||||
width = np.array([13/180*np.pi for i in direction_data])
|
width = np.array([13 / 180 * np.pi for i in direction_data])
|
||||||
colors = plt.cm.viridis(radii / max_range)
|
colors = plt.cm.viridis(radii / max_range)
|
||||||
|
|
||||||
ax = fig.add_subplot(111, projection='polar')
|
ax = fig.add_subplot(111, projection='polar')
|
||||||
|
|
|
@ -25,7 +25,7 @@ def get_used_countries():
|
||||||
|
|
||||||
@cache.memoize()
|
@cache.memoize()
|
||||||
def get_used_airports_by_country(sel_country):
|
def get_used_airports_by_country(sel_country):
|
||||||
query = db.session.query(Airport).filter(Airport.country_code == sel_country).filter(TakeoffLanding.airport_id==Airport.id).filter(TakeoffLanding.country_id == Country.gid).order_by(Airport.name).distinct(Airport.name)
|
query = db.session.query(Airport).filter(Airport.country_code == sel_country).filter(TakeoffLanding.airport_id == Airport.id).filter(TakeoffLanding.country_id == Country.gid).order_by(Airport.name).distinct(Airport.name)
|
||||||
return [used_airport for used_airport in query]
|
return [used_airport for used_airport in query]
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,15 +47,16 @@ def get_dates_for_airport(sel_airport):
|
||||||
def index():
|
def index():
|
||||||
today_beginning = datetime.combine(date.today(), time())
|
today_beginning = datetime.combine(date.today(), time())
|
||||||
|
|
||||||
senders_today = db.session.query(db.func.count(Sender.id)).filter(Sender.lastseen>=today_beginning).one()[0]
|
senders_today = db.session.query(db.func.count(Sender.id)).filter(Sender.lastseen >= today_beginning).one()[0]
|
||||||
receivers_today = db.session.query(db.func.count(Receiver.id)).filter(Receiver.lastseen>=today_beginning).one()[0]
|
receivers_today = db.session.query(db.func.count(Receiver.id)).filter(Receiver.lastseen >= today_beginning).one()[0]
|
||||||
takeoffs_today = db.session.query(db.func.count(TakeoffLanding.id)).filter(db.and_(TakeoffLanding.timestamp>=today_beginning, TakeoffLanding.is_takeoff==True)).one()[0]
|
takeoffs_today = db.session.query(db.func.count(TakeoffLanding.id)).filter(db.and_(TakeoffLanding.timestamp >= today_beginning, TakeoffLanding.is_takeoff is True)).one()[0]
|
||||||
landings_today = db.session.query(db.func.count(TakeoffLanding.id)).filter(db.and_(TakeoffLanding.timestamp>=today_beginning, TakeoffLanding.is_takeoff==False)).one()[0]
|
landings_today = db.session.query(db.func.count(TakeoffLanding.id)).filter(db.and_(TakeoffLanding.timestamp >= today_beginning, TakeoffLanding.is_takeoff is False)).one()[0]
|
||||||
sender_positions_today = db.session.query(db.func.sum(ReceiverStatistic.messages_count)).filter(ReceiverStatistic.date==date.today()).one()[0]
|
sender_positions_today = db.session.query(db.func.sum(ReceiverStatistic.messages_count)).filter(ReceiverStatistic.date == date.today()).one()[0]
|
||||||
sender_positions_total = db.session.query(db.func.sum(ReceiverStatistic.messages_count)).one()[0]
|
sender_positions_total = db.session.query(db.func.sum(ReceiverStatistic.messages_count)).one()[0]
|
||||||
|
|
||||||
last_logbook_entries = db.session.query(Logbook).order_by(Logbook.reference_timestamp.desc()).limit(10)
|
last_logbook_entries = db.session.query(Logbook).order_by(Logbook.reference_timestamp.desc()).limit(10)
|
||||||
return render_template("index.html",
|
return render_template(
|
||||||
|
"index.html",
|
||||||
senders_today=senders_today,
|
senders_today=senders_today,
|
||||||
receivers_today=receivers_today,
|
receivers_today=receivers_today,
|
||||||
takeoffs_today=takeoffs_today,
|
takeoffs_today=takeoffs_today,
|
||||||
|
@ -80,6 +81,7 @@ def sender_detail():
|
||||||
|
|
||||||
return render_template("sender_detail.html", title="Sender", sender=sender)
|
return render_template("sender_detail.html", title="Sender", sender=sender)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/range_view.png")
|
@bp.route("/range_view.png")
|
||||||
def range_view():
|
def range_view():
|
||||||
import io
|
import io
|
||||||
|
@ -210,24 +212,28 @@ def download_flight():
|
||||||
|
|
||||||
return send_file(buffer, as_attachment=True, attachment_filename="wtf.igc", mimetype="text/plain")
|
return send_file(buffer, as_attachment=True, attachment_filename="wtf.igc", mimetype="text/plain")
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/sender_ranking.html")
|
@bp.route("/sender_ranking.html")
|
||||||
def sender_ranking():
|
def sender_ranking():
|
||||||
sender_statistics = db.session.query(SenderStatistic) \
|
sender_statistics = db.session.query(SenderStatistic) \
|
||||||
.filter(db.and_(SenderStatistic.date==date.today(), SenderStatistic.is_trustworthy==True)) \
|
.filter(db.and_(SenderStatistic.date == date.today(), SenderStatistic.is_trustworthy is True)) \
|
||||||
.order_by(SenderStatistic.max_distance.desc()) \
|
.order_by(SenderStatistic.max_distance.desc()) \
|
||||||
.all()
|
.all()
|
||||||
|
|
||||||
return render_template("sender_ranking.html",
|
return render_template(
|
||||||
|
"sender_ranking.html",
|
||||||
title="Sender Ranking",
|
title="Sender Ranking",
|
||||||
ranking=sender_statistics)
|
ranking=sender_statistics)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/receiver_ranking.html")
|
@bp.route("/receiver_ranking.html")
|
||||||
def receiver_ranking():
|
def receiver_ranking():
|
||||||
receiver_statistics = db.session.query(ReceiverStatistic) \
|
receiver_statistics = db.session.query(ReceiverStatistic) \
|
||||||
.filter(db.and_(ReceiverStatistic.date==date.today(), ReceiverStatistic.is_trustworthy==True)) \
|
.filter(db.and_(ReceiverStatistic.date == date.today(), ReceiverStatistic.is_trustworthy is True)) \
|
||||||
.order_by(ReceiverStatistic.max_distance.desc()) \
|
.order_by(ReceiverStatistic.max_distance.desc()) \
|
||||||
.all()
|
.all()
|
||||||
|
|
||||||
return render_template("receiver_ranking.html",
|
return render_template(
|
||||||
|
"receiver_ranking.html",
|
||||||
title="Receiver Ranking",
|
title="Receiver Ranking",
|
||||||
ranking=receiver_statistics)
|
ranking=receiver_statistics)
|
||||||
|
|
|
@ -48,10 +48,9 @@ class Receiver(db.Model):
|
||||||
query = (
|
query = (
|
||||||
db.session.query(Airport, db.func.st_distance_sphere(self.location_wkt, Airport.location_wkt), db.func.st_azimuth(self.location_wkt, Airport.location_wkt))
|
db.session.query(Airport, db.func.st_distance_sphere(self.location_wkt, Airport.location_wkt), db.func.st_azimuth(self.location_wkt, Airport.location_wkt))
|
||||||
.filter(db.func.st_contains(db.func.st_buffer(Airport.location_wkt, 1), self.location_wkt))
|
.filter(db.func.st_contains(db.func.st_buffer(Airport.location_wkt, 1), self.location_wkt))
|
||||||
.filter(Airport.style.in_((2,4,5)))
|
.filter(Airport.style.in_((2, 4, 5)))
|
||||||
.order_by(db.func.st_distance_sphere(self.location_wkt, Airport.location_wkt).asc())
|
.order_by(db.func.st_distance_sphere(self.location_wkt, Airport.location_wkt).asc())
|
||||||
.limit(5)
|
.limit(5)
|
||||||
)
|
)
|
||||||
airports = [(airport,distance,azimuth) for airport, distance, azimuth in query]
|
airports = [(airport, distance, azimuth) for airport, distance, azimuth in query]
|
||||||
return airports
|
return airports
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from app import db
|
||||||
|
|
||||||
from sqlalchemy.dialects.postgresql import JSON
|
from sqlalchemy.dialects.postgresql import JSON
|
||||||
|
|
||||||
|
|
||||||
class SenderDirectionStatistic(db.Model):
|
class SenderDirectionStatistic(db.Model):
|
||||||
__tablename__ = "sender_direction_statistics"
|
__tablename__ = "sender_direction_statistics"
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from .aircraft_type import AircraftType
|
||||||
|
|
||||||
#from sqlalchemy.dialects.postgresql import ENUM
|
#from sqlalchemy.dialects.postgresql import ENUM
|
||||||
|
|
||||||
|
|
||||||
class SenderInfo(db.Model):
|
class SenderInfo(db.Model):
|
||||||
__tablename__ = "sender_infos"
|
__tablename__ = "sender_infos"
|
||||||
|
|
||||||
|
|
|
@ -60,4 +60,3 @@ class SenderPosition(db.Model):
|
||||||
location_mgrs = db.Column(db.String(15)) # full mgrs (15 chars)
|
location_mgrs = db.Column(db.String(15)) # full mgrs (15 chars)
|
||||||
location_mgrs_short = db.Column(db.String(9)) # reduced mgrs (9 chars), e.g. used for melissas range tool
|
location_mgrs_short = db.Column(db.String(9)) # reduced mgrs (9 chars), e.g. used for melissas range tool
|
||||||
agl = db.Column(db.Float(precision=2))
|
agl = db.Column(db.Float(precision=2))
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from .aircraft_type import AircraftType
|
||||||
|
|
||||||
from sqlalchemy.dialects.postgresql import ENUM
|
from sqlalchemy.dialects.postgresql import ENUM
|
||||||
|
|
||||||
|
|
||||||
class SenderPositionStatistic(db.Model):
|
class SenderPositionStatistic(db.Model):
|
||||||
__tablename__ = "sender_position_statistics"
|
__tablename__ = "sender_position_statistics"
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ from app.collect.gateway import transfer_from_redis_to_database
|
||||||
|
|
||||||
from app import db, celery
|
from app import db, celery
|
||||||
|
|
||||||
|
|
||||||
@celery.task(name="transfer_to_database")
|
@celery.task(name="transfer_to_database")
|
||||||
def transfer_to_database():
|
def transfer_to_database():
|
||||||
"""Transfer APRS data from Redis to database."""
|
"""Transfer APRS data from Redis to database."""
|
||||||
|
|
|
@ -137,6 +137,7 @@ def open_file(filename):
|
||||||
f = open(filename, "rt", encoding="latin-1")
|
f = open(filename, "rt", encoding="latin-1")
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
def get_sql_trustworthy(source_table_alias):
|
def get_sql_trustworthy(source_table_alias):
|
||||||
MIN_DISTANCE = 1000
|
MIN_DISTANCE = 1000
|
||||||
MAX_DISTANCE = 640000
|
MAX_DISTANCE = 640000
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class BaseConfig:
|
class BaseConfig:
|
||||||
SECRET_KEY = "i-like-ogn"
|
SECRET_KEY = "i-like-ogn"
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ class BaseConfig:
|
||||||
|
|
||||||
APRS_USER = "OGNPYTHON"
|
APRS_USER = "OGNPYTHON"
|
||||||
|
|
||||||
|
|
||||||
class DefaultConfig(BaseConfig):
|
class DefaultConfig(BaseConfig):
|
||||||
SQLALCHEMY_DATABASE_URI = os.environ.get("SQLALCHEMY_DATABASE_URI", "postgresql://postgres:postgres@localhost:5432/ogn")
|
SQLALCHEMY_DATABASE_URI = os.environ.get("SQLALCHEMY_DATABASE_URI", "postgresql://postgres:postgres@localhost:5432/ogn")
|
||||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||||
|
@ -37,11 +39,13 @@ class DefaultConfig(BaseConfig):
|
||||||
#"purge_old_data": {"task": "purge_old_data", "schedule": timedelta(hours=1), "kwargs": {"max_hours": 48}},
|
#"purge_old_data": {"task": "purge_old_data", "schedule": timedelta(hours=1), "kwargs": {"max_hours": 48}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DevelopmentConfig(BaseConfig):
|
class DevelopmentConfig(BaseConfig):
|
||||||
SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5432/ogn_test"
|
SQLALCHEMY_DATABASE_URI = "postgresql://postgres:postgres@localhost:5432/ogn_test"
|
||||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||||
SQLALCHEMY_ECHO = False
|
SQLALCHEMY_ECHO = False
|
||||||
|
|
||||||
|
|
||||||
configs = {
|
configs = {
|
||||||
'default': DefaultConfig,
|
'default': DefaultConfig,
|
||||||
'development': DevelopmentConfig,
|
'development': DevelopmentConfig,
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = F401, F841, E402, E501, E126
|
ignore = F401, F841, E402, E501, E126, E265
|
||||||
|
|
|
@ -76,7 +76,6 @@ class TestLogbook(TestBaseDB):
|
||||||
self.assertEqual(entries[0].takeoff_airport_id, self.koenigsdorf.id)
|
self.assertEqual(entries[0].takeoff_airport_id, self.koenigsdorf.id)
|
||||||
self.assertEqual(entries[0].landing_airport_id, self.koenigsdorf.id)
|
self.assertEqual(entries[0].landing_airport_id, self.koenigsdorf.id)
|
||||||
|
|
||||||
|
|
||||||
@unittest.skip('needs information about airport timezone')
|
@unittest.skip('needs information about airport timezone')
|
||||||
def test_takeoff_and_landing_on_different_days(self):
|
def test_takeoff_and_landing_on_different_days(self):
|
||||||
db.session.add(self.takeoff_koenigsdorf_dd0815)
|
db.session.add(self.takeoff_koenigsdorf_dd0815)
|
||||||
|
|
Ładowanie…
Reference in New Issue