Apply factory pattern WIP

pull/78/head
Konstantin Gründger 2019-09-12 22:53:42 +02:00 zatwierdzone przez Meisterschueler
rodzic 34d9c39ab6
commit b13064cf73
20 zmienionych plików z 92 dodań i 104 usunięć

Wyświetl plik

@ -1,12 +1,10 @@
language: python
env:
- OGN_CONFIG_MODULE='config/test.py'
python:
- 3.5
- 3.6
- 3.7-dev
- 3.7
- 3.8-dev
addons:
postgresql: "9.6"

Wyświetl plik

@ -7,21 +7,32 @@ from celery import Celery
from app.flask_celery import make_celery
# Initialize Flask
app = Flask(__name__)
bootstrap = Bootstrap()
db = SQLAlchemy()
cache = Cache()
# Load the configuration
app.config.from_object('app.config.default')
app.config.from_envvar("OGN_CONFIG_MODULE", silent=True)
def create_app(config_name='development'):
# Initialize Flask
app = Flask(__name__)
# Initialize other things
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
cache = Cache(app)
celery = make_celery(app)
# Load the configuration
if config_name == 'testing':
app.config.from_object('app.config.test')
else:
app.config.from_object('app.config.default')
app.config.from_envvar("OGN_CONFIG_MODULE", silent=True)
from app.main import bp as bp_main
app.register_blueprint(bp_main)
# Initialize other things
bootstrap.init_app(app)
db.init_app(app)
cache.init_app(app)
#migrate = Migrate(app, db)
#celery = make_celery(app)
from app.main import bp as bp_main
app.register_blueprint(bp_main)
from app import commands
#from app import commands
return app

Wyświetl plik

@ -2,12 +2,11 @@ from sqlalchemy import distinct
from sqlalchemy.sql import null, and_, func, not_, case
from sqlalchemy.dialects import postgresql
from sqlalchemy.dialects.postgresql import insert
from flask import current_app
from app.model import Country, DeviceInfo, DeviceInfoOrigin, AircraftBeacon, ReceiverBeacon, Device, Receiver
from app.utils import get_ddb, get_flarmnet
from app import app
def upsert(session, model, rows, update_cols):
"""Insert rows in model. On conflicting update columns if new value IS NOT NULL."""
@ -46,7 +45,7 @@ def import_ddb(session, logger=None):
"""Import registered devices from the DDB."""
if logger is None:
logger = app.logger
logger = current_app.logger
logger.info("Import registered devices fom the DDB...")
counter = update_device_infos(session, DeviceInfoOrigin.OGN_DDB)
@ -60,7 +59,7 @@ def update_country_code(session, logger=None):
"""Update country code in receivers table if None."""
if logger is None:
logger = app.logger
logger = current_app.logger
update_receivers = (
session.query(Receiver)

Wyświetl plik

@ -1,18 +1,17 @@
from sqlalchemy import and_, or_, insert, update, exists, between
from sqlalchemy.sql import func, null
from sqlalchemy.sql.expression import true, false
from flask import current_app
from app.model import TakeoffLanding, Logbook, AircraftBeacon
from app.utils import date_to_timestamps
from app import app
def update_entries(session, date, logger=None):
"""Add/update logbook entries."""
if logger is None:
logger = app.logger
logger = current_app.logger
logger.info("Compute logbook.")
@ -167,7 +166,7 @@ def update_max_altitudes(session, date, logger=None):
"""Add max altitudes in logbook when flight is complete (takeoff and landing)."""
if logger is None:
logger = app.logger
logger = current_app.logger
logger.info("Update logbook max altitude.")

Wyświetl plik

@ -1,18 +1,17 @@
from sqlalchemy import Date
from sqlalchemy import and_, insert, update, exists, between
from sqlalchemy.sql import func, null
from flask import current_app
from app.model import AircraftBeacon, ReceiverCoverage
from app.utils import date_to_timestamps
from app import app
def update_entries(session, date, logger=None):
"""Create receiver coverage stats for Melissas ognrange."""
if logger is None:
logger = app.logger
logger = current_app.logger
logger.info("Compute receiver coverages.")

Wyświetl plik

@ -1,12 +1,11 @@
from flask import current_app
from sqlalchemy import insert, distinct, between, literal
from sqlalchemy.sql import null, and_, func, or_, update
from sqlalchemy.sql.expression import case
from app.model import AircraftBeacon, DeviceStats, Country, CountryStats, ReceiverStats, ReceiverBeacon, RelationStats, Receiver, Device
from app.utils import date_to_timestamps
from app import app
# 40dB@10km is enough for 640km
MAX_PLAUSIBLE_QUALITY = 40
@ -16,7 +15,7 @@ def create_device_stats(session, date, logger=None):
"""Add/update device stats."""
if logger is None:
logger = app.logger
logger = current_app.logger
(start, end) = date_to_timestamps(date)
@ -83,7 +82,7 @@ def create_receiver_stats(session, date, logger=None):
"""Add/update receiver stats."""
if logger is None:
logger = app.logger
logger = current_app.logger
(start, end) = date_to_timestamps(date)
@ -155,7 +154,7 @@ def create_receiver_stats(session, date, logger=None):
def create_country_stats(session, date, logger=None):
if logger is None:
logger = app.logger
logger = current_app.logger
(start, end) = date_to_timestamps(date)
@ -181,7 +180,7 @@ def update_device_stats_jumps(session, date, logger=None):
"""Update device stats jumps."""
if logger is None:
logger = app.logger
logger = current_app.logger
(start, end) = date_to_timestamps(date)
@ -237,7 +236,7 @@ def create_relation_stats(session, date, logger=None):
"""Add/update relation stats."""
if logger is None:
logger = app.logger
logger = current_app.logger
(start, end) = date_to_timestamps(date)
@ -274,7 +273,7 @@ def update_qualities(session, date, logger=None):
"""Calculate relative qualities of receivers and devices."""
if logger is None:
logger = app.logger
logger = current_app.logger
# Calculate avg quality of devices
dev_sq = session.query(RelationStats.device_id, func.avg(RelationStats.quality).label("quality")).filter(RelationStats.date == date).group_by(RelationStats.device_id).subquery()
@ -339,7 +338,7 @@ def update_receivers(session, logger=None):
"""Update receivers with stats."""
if logger is None:
logger = app.logger
logger = current_app.logger
receiver_stats = (
session.query(
@ -394,7 +393,7 @@ def update_devices(session, logger=None):
"""Update devices with stats."""
if logger is None:
logger = app.logger
logger = current_app.logger
device_stats = (
session.query(

Wyświetl plik

@ -1,19 +1,18 @@
from datetime import timedelta
from flask import current_app
from sqlalchemy import and_, or_, insert, between, exists
from sqlalchemy.sql import func, null
from sqlalchemy.sql.expression import case
from app.model import AircraftBeacon, TakeoffLanding, Airport
from app import app
def update_entries(session, start, end, logger=None):
"""Compute takeoffs and landings."""
if logger is None:
logger = app.logger
logger = current_app.logger
logger.info("Compute takeoffs and landings.")

Wyświetl plik

@ -1,5 +1,3 @@
from app import app
from .database import user_cli as database_cli
from .export import user_cli as export_cli
from .flights import user_cli as flights_cli
@ -7,9 +5,10 @@ from .gateway import user_cli as gateway_cli
from .logbook import user_cli as logbook_cli
from .stats import user_cli as stats_cli
app.cli.add_command(database_cli)
app.cli.add_command(export_cli)
app.cli.add_command(flights_cli)
app.cli.add_command(gateway_cli)
app.cli.add_command(logbook_cli)
app.cli.add_command(stats_cli)
def register(app):
app.cli.add_command(database_cli)
app.cli.add_command(export_cli)
app.cli.add_command(flights_cli)
app.cli.add_command(gateway_cli)
app.cli.add_command(logbook_cli)
app.cli.add_command(stats_cli)

Wyświetl plik

@ -1,3 +1,4 @@
from flask import current_app
from flask.cli import AppGroup
import click
@ -8,7 +9,6 @@ from app.collect.database import update_device_infos, update_country_code
from app.model import *
from app.utils import get_airports, get_days
from app import app
from app import db
user_cli = AppGroup("database")
@ -36,8 +36,8 @@ def get_database_days(start, end):
@user_cli.command("info")
def info():
print(app.config)
print(app.config["SQLALCHEMY_DATABASE_URI"])
print(current_app.config)
print(current_app.config["SQLALCHEMY_DATABASE_URI"])
@user_cli.command("init")

Wyświetl plik

@ -1,11 +1,10 @@
from flask import current_app
from flask.cli import AppGroup
import click
from ogn.client import AprsClient
from app.gateway.bulkimport import ContinuousDbFeeder
from app import app
user_cli = AppGroup("gateway")
user_cli.help = "Connection to APRS servers."
@ -21,14 +20,14 @@ def run(aprs_user="anon-dev"):
print("aprs_user must be a string of 3-9 characters.")
return
app.logger.warning("Start ogn gateway")
current_app.logger.warning("Start ogn gateway")
client = AprsClient(aprs_user)
client.connect()
try:
client.run(callback=saver.add, autoreconnect=True)
except KeyboardInterrupt:
app.logger.warning("\nStop ogn gateway")
current_app.logger.warning("\nStop ogn gateway")
saver.flush()
client.disconnect()

Wyświetl plik

@ -1,6 +1,7 @@
from datetime import datetime, timedelta
from io import StringIO
from flask import current_app
from flask.cli import AppGroup
import click
from tqdm import tqdm
@ -13,7 +14,6 @@ from app.utils import open_file
from app.gateway.process_tools import *
from app import db
from app import app
user_cli = AppGroup("bulkimport")
user_cli.help = "Tools for accelerated data import."
@ -91,16 +91,16 @@ def string_to_message(raw_string, reference_date):
try:
message = parse(raw_string, reference_date)
except NotImplementedError as e:
app.logger.error("No parser implemented for message: {}".format(raw_string))
current_app.logger.error("No parser implemented for message: {}".format(raw_string))
return None
except ParseError as e:
app.logger.error("Parsing error with message: {}".format(raw_string))
current_app.logger.error("Parsing error with message: {}".format(raw_string))
return None
except TypeError as e:
app.logger.error("TypeError with message: {}".format(raw_string))
current_app.logger.error("TypeError with message: {}".format(raw_string))
return None
except Exception as e:
app.logger.error("Other Exception with string: {}".format(raw_string))
current_app.logger.error("Other Exception with string: {}".format(raw_string))
return None
# update reference receivers and distance to the receiver
@ -160,7 +160,7 @@ class ContinuousDbFeeder:
self.receiver_buffer.write(complete_message)
self.receiver_buffer.write("\n")
else:
app.logger.error("Ignore beacon_type: {}".format(message["beacon_type"]))
current_app.logger.error("Ignore beacon_type: {}".format(message["beacon_type"]))
return
if datetime.utcnow() - self.last_flush >= timedelta(seconds=20):
@ -243,7 +243,7 @@ class FileDbFeeder:
self.receiver_buffer.write(complete_message)
self.receiver_buffer.write("\n")
else:
app.logger.error("Ignore beacon_type: {}".format(message["beacon_type"]))
current_app.logger.error("Ignore beacon_type: {}".format(message["beacon_type"]))
return
def prepare(self):

Wyświetl plik

@ -1,6 +1,5 @@
[program:celerybeat]
environment=OGN_CONFIG_MODULE='config/default.py'
command=/home/pi/venv/bin/celery -A app.collect beat -l info
command=/home/pi/ogn-python/venv/bin/celery -A app.collect beat -l info
directory=/home/pi/ogn-python
user=pi

Wyświetl plik

@ -1,5 +1,4 @@
[program:celery]
environment=OGN_CONFIG_MODULE='config/default.py'
command=/home/pi/ogn-python/venv/bin/celery -A app.collect worker -l info
directory=/home/pi/ogn-python

Wyświetl plik

@ -1,5 +1,4 @@
[program:flower]
environment=OGN_CONFIG_MODULE='config/default.py'
command=/home/pi/ogn-python/venv/bin/celery flower -A app.celery --port=5555 -l info
directory=/home/pi/ogn-python

Wyświetl plik

@ -1,5 +1,4 @@
[program:gunicorn]
environment=OGN_CONFIG_MODULE='config/default.py'
command=/home/pi/ogn-python/venv/bin/gunicorn --bind :5000 ogn_python:app
directory=/home/pi/ogn-python

Wyświetl plik

@ -1,7 +1,6 @@
[program:ogn-feeder]
environment=OGN_CONFIG_MODULE='config/default.py'
command=/home/pi/ogn-python/venv/bin/python -m flask gateway run
directory=/home/pi/ogn_python
directory=/home/pi/ogn-python
user=pi
stderr_logfile=/var/log/supervisor/ogn-feeder.log

Wyświetl plik

@ -1,5 +1,13 @@
from app import app
import os
from flask_migrate import Migrate
from app import create_app, db
from app.commands import register
if __name__ == '__main__':
app.run()
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
migrate = Migrate(app, db)
register(app)
@app.shell_context_processor
def make_shell_context():
return dict(app=app, db=db)

Wyświetl plik

@ -1,36 +1,18 @@
import unittest
import os
os.environ["OGN_CONFIG_MODULE"] = "config/test.py"
from app import db # noqa: E402
from app import create_app, db
class TestBaseDB(unittest.TestCase):
@classmethod
def setUpClass(cls):
db.session.execute("CREATE EXTENSION IF NOT EXISTS postgis;")
db.session.commit()
db.drop_all()
def setUp(self):
self.app = create_app('testing')
self.app_context = self.app.app_context()
self.app_context.push()
db.create_all()
def setUp(self):
pass
def tearDown(self):
db.session.execute(
"""
DELETE FROM aircraft_beacons;
DELETE FROM receiver_beacons;
DELETE FROM takeoff_landings;
DELETE FROM logbook;
DELETE FROM receiver_coverages;
DELETE FROM device_stats;
DELETE FROM receiver_stats;
DELETE FROM receivers;
DELETE FROM devices;
"""
)
db.session.remove()
db.drop_all()
self.app_context.pop()
if __name__ == "__main__":

Wyświetl plik

@ -9,6 +9,8 @@ from app.collect.logbook import update_entries
class TestLogbook(TestBaseDB):
def setUp(self):
super().setUp()
# Create basic data and insert
self.dd0815 = Device(address="DD0815")
self.dd4711 = Device(address="DD4711")

Wyświetl plik

@ -1,17 +1,16 @@
import unittest
import os
from tests.base import TestBaseDB, db
from flask import current_app
from app.model import DeviceInfo
from app.commands.database import import_file
from app import app
from tests.base import TestBaseDB, db
class TestDatabase(TestBaseDB):
def test_import_ddb_file(self):
runner = app.test_cli_runner()
runner = current_app.test_cli_runner()
result = runner.invoke(import_file, [os.path.dirname(__file__) + "/../custom_ddb.txt"])
self.assertEqual(result.exit_code, 0)