overhaul of application structure, added new configs, switched to current_app contextual implementation, proper flask app creation and handling

This commit is contained in:
Xevion
2020-06-20 18:50:46 -05:00
parent 45a49c7c85
commit a2bde58ace
11 changed files with 93 additions and 49 deletions

View File

@@ -1,2 +1,2 @@
FLASK_APP=wsgi.py
FLASK_APP=trivia.create_app
FLASK_ENV=development

8
setup.py Normal file
View File

@@ -0,0 +1,8 @@
from setuptools import setup
setup(
name='flask-demo',
entry_points= {
'con'
}
)

View File

@@ -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()

5
trivia/__main__.py Normal file
View File

@@ -0,0 +1,5 @@
from create_app import create_app
if __name__ == '__main__':
app = create_app()
app.run()

View File

@@ -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

22
trivia/config.py Normal file
View File

@@ -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

23
trivia/create_app.py Normal file
View File

@@ -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

View File

@@ -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.

View File

@@ -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;
}
</style>
</head>
<body>
@@ -64,7 +75,7 @@
<table class="fixed_headers" style="height:100%;width:100%; position: absolute; top: 0; bottom: 0; left: 0; right: 0;">
<thead>
<tr>
<th>Rank</th>
<th style="height: 10%;">Rank</th>
<th>Team Name</th>
{% for i in range(scoreCount) %}
<th>{{ i + 1 }}</th>
@@ -73,7 +84,7 @@
</thead>
<tbody>
{% for team in teams %}
<tr>
<tr id="{{ team.id }}">
<td>{{ range(1, teams | length) | random }}</td>
<td>{{ team.name }}</td>
{% for score in team.scores %}

View File

@@ -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

10
wsgi.py
View File

@@ -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)