From a2bde58aceb508ca04b672351e5a3e0f9c57fb19 Mon Sep 17 00:00:00 2001 From: Xevion Date: Sat, 20 Jun 2020 18:50:46 -0500 Subject: [PATCH] overhaul of application structure, added new configs, switched to current_app contextual implementation, proper flask app creation and handling --- .flaskenv | 2 +- setup.py | 8 ++++++++ trivia/__init__.py | 21 --------------------- trivia/__main__.py | 5 +++++ trivia/api.py | 10 ++++------ trivia/config.py | 22 ++++++++++++++++++++++ trivia/create_app.py | 23 +++++++++++++++++++++++ trivia/routes.py | 6 ++---- trivia/templates/index.html | 17 ++++++++++++++--- trivia/utils.py | 18 ++++++++++++++---- wsgi.py | 10 ---------- 11 files changed, 93 insertions(+), 49 deletions(-) create mode 100644 setup.py create mode 100644 trivia/__main__.py create mode 100644 trivia/config.py create mode 100644 trivia/create_app.py delete mode 100644 wsgi.py diff --git a/.flaskenv b/.flaskenv index d80687f..85b6b69 100644 --- a/.flaskenv +++ b/.flaskenv @@ -1,2 +1,2 @@ -FLASK_APP=wsgi.py +FLASK_APP=trivia.create_app FLASK_ENV=development \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..20151cb --- /dev/null +++ b/setup.py @@ -0,0 +1,8 @@ +from setuptools import setup + +setup( + name='flask-demo', + entry_points= { + 'con' + } +) \ No newline at end of file diff --git a/trivia/__init__.py b/trivia/__init__.py index 5452bfb..e69de29 100644 --- a/trivia/__init__.py +++ b/trivia/__init__.py @@ -1,21 +0,0 @@ -""" -__init__.py -""" -from collections import namedtuple - -from apscheduler.schedulers.background import BackgroundScheduler -from flask import Flask - -app = Flask(__name__) - -# Simple fake 'class' for passing to jinja templates -Team = namedtuple('Team', ['id', 'name', 'scores']) - -from trivia import routes, api, utils - -# Setup a scheduler for automatically refreshing data -scheduler = BackgroundScheduler() -scheduler.start() -scheduler.add_job(func=utils.refreshScores, trigger="interval", seconds=5) - -utils.refreshScores() diff --git a/trivia/__main__.py b/trivia/__main__.py new file mode 100644 index 0000000..0a3ebdc --- /dev/null +++ b/trivia/__main__.py @@ -0,0 +1,5 @@ +from create_app import create_app + +if __name__ == '__main__': + app = create_app() + app.run() \ No newline at end of file diff --git a/trivia/api.py b/trivia/api.py index 871912a..ea1ed2e 100644 --- a/trivia/api.py +++ b/trivia/api.py @@ -6,13 +6,11 @@ Handles backend routes assisting import json import time -from flask import request, make_response - -from trivia import app +from flask import request, make_response, current_app -@app.route("/api/scores") -@app.route("/api/scores/") +@current_app.route("/api/scores") +@current_app.route("/api/scores/") def scores(): """ Used for refreshing client-side table data. Returns a JSON response with all data necessary to build the table. @@ -34,6 +32,6 @@ def scores(): except KeyError: pass # Header was not supplied. Ignore. except ValueError: - app.logger.warning('If-Modified-Since Header could not be parsed.') # Header could not be parsed. + current_app.logger.warning('If-Modified-Since Header could not be parsed.') # Header could not be parsed. return r, status_code diff --git a/trivia/config.py b/trivia/config.py new file mode 100644 index 0000000..6430c2e --- /dev/null +++ b/trivia/config.py @@ -0,0 +1,22 @@ +""" +config.py + + +""" + +configs = { + 'production': 'trivia.config.Config', + 'development': 'trivia.config.Config', + 'demo': 'trivia.config.DemoConfig' +} + + +class Config(object): + SCORE_FILE = 'scores.json' + DEMO = False + + + +class DemoConfig(Config): + SCORE_FILE = 'demo.json' + DEMO = True diff --git a/trivia/create_app.py b/trivia/create_app.py new file mode 100644 index 0000000..66dce45 --- /dev/null +++ b/trivia/create_app.py @@ -0,0 +1,23 @@ +from apscheduler.schedulers.background import BackgroundScheduler +from flask import Flask + +from trivia import utils +from trivia.config import configs + + +def create_app(env=None): + app = Flask(__name__) + + if not env: + env = app.config['ENV'] + app.config.from_object(configs[env]) + + # Setup a scheduler for automatically refreshing data + scheduler = BackgroundScheduler() + scheduler.start() + scheduler.add_job(func=utils.refreshScores, trigger="interval", seconds=5) + + with app.app_context(): + utils.refreshScores() + + return app diff --git a/trivia/routes.py b/trivia/routes.py index bc62226..758419f 100644 --- a/trivia/routes.py +++ b/trivia/routes.py @@ -3,12 +3,10 @@ routes.py Handles user frontend routes. """ -from flask import render_template - -from trivia import app +from flask import render_template, current_app -@app.route("/") +@current_app.route("/") def index(): """ Handles the frontend user index. diff --git a/trivia/templates/index.html b/trivia/templates/index.html index 7e52451..dd30735 100644 --- a/trivia/templates/index.html +++ b/trivia/templates/index.html @@ -16,7 +16,8 @@ .fixed_headers th, .fixed_headers td { - font-family: arial, serif; + font-family: Candara, serif; + font-size: large; font-weight: bold; /*padding: 5px;*/ text-align: left; @@ -57,6 +58,16 @@ .fixed_headers tbody tr:nth-child(even) { background-color: #DDD; } + + th, td > div { + {#width: 100%;#} + height: 10%; + overflow: hidden; + } + + th, td { + height: 20px; + } @@ -64,7 +75,7 @@ - + {% for i in range(scoreCount) %} @@ -73,7 +84,7 @@ {% for team in teams %} - + {% for score in team.scores %} diff --git a/trivia/utils.py b/trivia/utils.py index 716f2d4..0e2f545 100644 --- a/trivia/utils.py +++ b/trivia/utils.py @@ -5,9 +5,14 @@ Stores important backend application functionality. """ import json import os +from collections import namedtuple from typing import List -from trivia import Team, app +# Simple fake 'class' for passing to jinja templates +# from trivia import app +from flask import current_app + +Team = namedtuple('Team', ['id', 'name', 'scores']) # Generate paths BASE_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -41,7 +46,7 @@ def refreshScores() -> None: # Update tracking var lastChange = curChange - app.logger.debug('Attempting to load and parse scores file.') + current_app.logger.debug('Attempting to load and parse scores file.') with open(SCORES_FILE) as file: temp = json.load(file) @@ -53,11 +58,16 @@ def refreshScores() -> None: scores=team['scores'] ) for team in temp ] - app.logger.debug(f'Successfully loaded ({len(temp)} teams).') + current_app.logger.debug(f'Successfully loaded ({len(temp)} teams).') global teams teams = temp # If invalid or inaccessible, simply do nothing. except json.JSONDecodeError: - app.logger.error('Scores file could not be opened or parsed.', print_exc=True) + current_app.logger.error('Scores file could not be opened or parsed.', print_exc=True) + + +def generateDemo() -> None: + pass + diff --git a/wsgi.py b/wsgi.py deleted file mode 100644 index 86ba343..0000000 --- a/wsgi.py +++ /dev/null @@ -1,10 +0,0 @@ -""" -wsgi.py - -Simple launcher file for project. -""" - -from trivia import app - -if __name__ == "__main__": - app.run(host="0.0.0.0", use_reloader=False)
RankRank Team Name{{ i + 1 }}
{{ range(1, teams | length) | random }} {{ team.name }}