mirror of
https://github.com/sartography/uva-covid19-testing-communicator.git
synced 2025-02-23 20:38:13 +00:00
Adresses all but 6 and 8
This commit is contained in:
parent
c97caa9ae5
commit
321e0c1dad
@ -21,7 +21,7 @@ from flask_marshmallow import Marshmallow
|
|||||||
from flask_migrate import Migrate
|
from flask_migrate import Migrate
|
||||||
from flask_paginate import Pagination, get_page_parameter
|
from flask_paginate import Pagination, get_page_parameter
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func, and_, case
|
||||||
from sentry_sdk.integrations.flask import FlaskIntegration
|
from sentry_sdk.integrations.flask import FlaskIntegration
|
||||||
from webassets import Bundle
|
from webassets import Bundle
|
||||||
from flask_executor import Executor
|
from flask_executor import Executor
|
||||||
@ -119,7 +119,6 @@ def superuser(f):
|
|||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
@superuser
|
@superuser
|
||||||
def page_not_found(e):
|
def page_not_found(e):
|
||||||
@ -141,30 +140,6 @@ def daterange(start, stop, days = 1, hours = 0):
|
|||||||
def date2datetime(_date):
|
def date2datetime(_date):
|
||||||
return datetime.combine(_date, datetime.min.time())
|
return datetime.combine(_date, datetime.min.time())
|
||||||
|
|
||||||
def make_sample_histogram(samples, _range=None):
|
|
||||||
if _range == None:
|
|
||||||
start = None
|
|
||||||
end = None
|
|
||||||
_range = (start,end)
|
|
||||||
days_in_search = (_range[1] - _range[0]).days
|
|
||||||
if days_in_search <= 1:
|
|
||||||
hours = 2
|
|
||||||
days = 0
|
|
||||||
elif days_in_search <= 3:
|
|
||||||
hours = 4
|
|
||||||
days = 0
|
|
||||||
else:
|
|
||||||
hours = 0
|
|
||||||
days = 1
|
|
||||||
bounds = daterange(_range[0], _range[1], days=days, hours=hours)
|
|
||||||
counts = [0 for i in range(len(bounds))]
|
|
||||||
for entry in samples:
|
|
||||||
for i in range(len(bounds) - 1):
|
|
||||||
if entry.date > bounds[i] and entry.date < bounds[i+1]:
|
|
||||||
counts[i] += 1
|
|
||||||
break
|
|
||||||
return bounds, counts
|
|
||||||
|
|
||||||
@app.route('/', methods=['GET', 'POST'])
|
@app.route('/', methods=['GET', 'POST'])
|
||||||
@superuser
|
@superuser
|
||||||
def index():
|
def index():
|
||||||
@ -173,8 +148,7 @@ def index():
|
|||||||
|
|
||||||
form = forms.SearchForm(request.form)
|
form = forms.SearchForm(request.form)
|
||||||
action = BASE_HREF + "/"
|
action = BASE_HREF + "/"
|
||||||
samples = db.session.query(Sample).order_by(Sample.date.desc())
|
|
||||||
|
|
||||||
if request.method == "POST" or request.args.get('cancel') == 'true':
|
if request.method == "POST" or request.args.get('cancel') == 'true':
|
||||||
session["index_filter"] = {} # Clear out the session if it is invalid.
|
session["index_filter"] = {} # Clear out the session if it is invalid.
|
||||||
|
|
||||||
@ -190,7 +164,7 @@ def index():
|
|||||||
session["index_filter"]["location"] = form.location.data
|
session["index_filter"]["location"] = form.location.data
|
||||||
if form.compute_id.data:
|
if form.compute_id.data:
|
||||||
session["index_filter"]["compute_id"] = form.compute_id.data
|
session["index_filter"]["compute_id"] = form.compute_id.data
|
||||||
|
samples = db.session.query(Sample).order_by(Sample.date.desc())
|
||||||
# Store previous form submission settings in the session, so they are preseved through pagination.
|
# Store previous form submission settings in the session, so they are preseved through pagination.
|
||||||
filtered_samples = samples
|
filtered_samples = samples
|
||||||
if "index_filter" in session:
|
if "index_filter" in session:
|
||||||
@ -241,6 +215,7 @@ def index():
|
|||||||
csv = __make_csv(filtered_samples)
|
csv = __make_csv(filtered_samples)
|
||||||
return send_file(csv, attachment_filename='data_export.csv', as_attachment=True)
|
return send_file(csv, attachment_filename='data_export.csv', as_attachment=True)
|
||||||
|
|
||||||
|
|
||||||
weekday_totals = [0 for _ in range(7)] # Mon, Tues, ...
|
weekday_totals = [0 for _ in range(7)] # Mon, Tues, ...
|
||||||
hour_totals = [0 for _ in range(24)] # 12AM, 1AM, ...
|
hour_totals = [0 for _ in range(24)] # 12AM, 1AM, ...
|
||||||
|
|
||||||
@ -260,53 +235,67 @@ def index():
|
|||||||
two_weeks_ago = one_week_ago - timedelta(7)
|
two_weeks_ago = one_week_ago - timedelta(7)
|
||||||
chart_ticks = []
|
chart_ticks = []
|
||||||
|
|
||||||
if filtered_samples.count() > 0:
|
if days_in_search <= 1:
|
||||||
if days_in_search == 1:
|
timeFormat = "%I:%M %p"
|
||||||
timeFormat = "%I:%M %p"
|
hours = 2
|
||||||
elif days_in_search <= 3:
|
days = 0
|
||||||
timeFormat = "%m/%d %I %p"
|
elif days_in_search <= 3:
|
||||||
else:
|
timeFormat = "%m/%d %I %p"
|
||||||
timeFormat = "%m/%d"
|
hours = 4
|
||||||
bounds = []
|
days = 0
|
||||||
|
else:
|
||||||
|
timeFormat = "%m/%d"
|
||||||
|
hours = 0
|
||||||
|
days = 1
|
||||||
|
|
||||||
for entry in filtered_samples:
|
bounds = daterange(filters["start_date"], filters["end_date"], days=days, hours=hours)
|
||||||
if entry.location not in location_charts_data:
|
cases = [ ]
|
||||||
location_charts_data[entry.location] = dict()
|
|
||||||
location_stats_data[entry.location] = { "one_week_ago" : 0,
|
for i in range(len(bounds) - 1):
|
||||||
"two_week_ago" : 0,
|
cases.append(func.count(case([(and_(Sample.date >= bounds[i], Sample.date <= bounds[i+1]), 1)])))
|
||||||
"today" : 0 }
|
|
||||||
|
q = db.session.query(Sample.location, Sample.station,
|
||||||
|
*cases\
|
||||||
|
).group_by(Sample.location, Sample.station)
|
||||||
|
|
||||||
if entry.station not in location_charts_data[entry.location]:
|
for result in q:
|
||||||
samples_at_station = filtered_samples\
|
location, station = result[0], result[1]
|
||||||
.filter(Sample.location == entry.location)\
|
if any(x > 0 for x in result[2:]):
|
||||||
.filter(Sample.station == entry.station)
|
if location not in location_charts_data: location_charts_data[location] = dict()
|
||||||
|
location_charts_data[location][station] = result[2:]
|
||||||
|
|
||||||
bounds, counts = make_sample_histogram(samples_at_station, (filters["start_date"],filters["end_date"]))
|
# from sqlalchemy.dialects import postgresql
|
||||||
location_charts_data[entry.location][entry.station] = counts
|
# logging.info(str(q.statement.compile(dialect=postgresql.dialect())))
|
||||||
|
|
||||||
weekday_totals[entry.date.weekday()] += 1
|
|
||||||
hour_totals[entry.date.hour] += 1
|
|
||||||
|
|
||||||
if entry.date.date() >= two_weeks_ago:
|
for location in location_charts_data:
|
||||||
location_stats_data[entry.location]["two_week_ago"] += 1
|
location_stats_data[location] = {
|
||||||
if entry.date.date() >= one_week_ago:
|
"one_week_ago" : 23,
|
||||||
location_stats_data[entry.location]["one_week_ago"] += 1
|
"two_week_ago" : 543,
|
||||||
if entry.date.date() >= today:
|
"today" : 2623
|
||||||
location_stats_data[entry.location]["today"] += 1
|
}
|
||||||
|
for station in location_charts_data[location]:
|
||||||
chart_ticks = []
|
pass
|
||||||
for i in range(len(bounds) - 1):
|
|
||||||
chart_ticks.append(f"{bounds[i].strftime(timeFormat)} - {bounds[i+1].strftime(timeFormat)}")
|
chart_ticks = []
|
||||||
|
for i in range(len(bounds) - 1):
|
||||||
|
chart_ticks.append(f"{bounds[i].strftime(timeFormat)} - {bounds[i+1].strftime(timeFormat)}")
|
||||||
|
|
||||||
for location in location_charts_data:
|
for location in location_stats_data:
|
||||||
overall_stat_data["one_week_ago"] += location_stats_data[entry.location]["one_week_ago"]
|
overall_chart_data[location] = np.sum([location_charts_data[location][station] for station in location_charts_data[location]],axis=0).tolist()
|
||||||
overall_stat_data["two_week_ago"] += location_stats_data[entry.location]["two_week_ago"]
|
|
||||||
overall_stat_data["today"] += location_stats_data[entry.location]["today"]
|
# overall_stat_data["one_week_ago"] += location_stats_data[entry.location]["one_week_ago"]
|
||||||
|
# overall_stat_data["two_week_ago"] += location_stats_data[entry.location]["two_week_ago"]
|
||||||
|
# overall_stat_data["today"] += location_stats_data[entry.location]["today"]
|
||||||
|
|
||||||
|
for entry in filtered_samples:
|
||||||
|
weekday_totals[entry.date.weekday()] += 1
|
||||||
|
hour_totals[entry.date.hour] += 1
|
||||||
|
|
||||||
overall_chart_data[location] = np.sum([location_charts_data[location][station] for station in location_charts_data[location]],axis=0).tolist()
|
weekday_totals = [round(i/days_in_search,2) for i in weekday_totals] # Mon, Tues, ...
|
||||||
|
hour_totals = [round(i/days_in_search,2) for i in hour_totals] # 12AM, 1AM, ...
|
||||||
dates = {
|
|
||||||
"today" : filters["end_date"].strftime("%m/%d/%Y"),
|
dates = {
|
||||||
|
"today" : (filters["end_date"] - timedelta(1)).strftime("%m/%d/%Y"),
|
||||||
"range" : filters["start_date"].strftime("%m/%d/%Y") + " - " + (filters["end_date"] - timedelta(1)).strftime("%m/%d/%Y"),
|
"range" : filters["start_date"].strftime("%m/%d/%Y") + " - " + (filters["end_date"] - timedelta(1)).strftime("%m/%d/%Y"),
|
||||||
"one_week_ago" : one_week_ago.strftime("%m/%d/%Y"),
|
"one_week_ago" : one_week_ago.strftime("%m/%d/%Y"),
|
||||||
"two_weeks_ago" : two_weeks_ago.strftime("%m/%d/%Y"),
|
"two_weeks_ago" : two_weeks_ago.strftime("%m/%d/%Y"),
|
||||||
@ -340,21 +329,6 @@ def index():
|
|||||||
hour_totals = hour_totals,
|
hour_totals = hour_totals,
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
# # Check for Unresponsive
|
|
||||||
# for loc_code in active_stations:
|
|
||||||
# if loc_code not in location_data:
|
|
||||||
# location_dict["datasets"].append({
|
|
||||||
# "label": loc_code,
|
|
||||||
# "borderColor": f'rgba(128,128,128,.7)',
|
|
||||||
# "pointBorderColor": f'rgba(128,128,128,1)',
|
|
||||||
# "borderWidth": 10,
|
|
||||||
# "data": [{
|
|
||||||
# "x": session["index_filter"]["start_date"], "y": i
|
|
||||||
# }, ],
|
|
||||||
# })
|
|
||||||
# i += 1
|
|
||||||
|
|
||||||
@app.route('/activate', methods=['GET', 'POST'])
|
@app.route('/activate', methods=['GET', 'POST'])
|
||||||
@superuser
|
@superuser
|
||||||
def activate_station():
|
def activate_station():
|
||||||
|
@ -102,7 +102,7 @@ body
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
color: #525f7f;
|
color: #525f7f;
|
||||||
background-color: #f8f9fe;
|
background-color: #393b83;
|
||||||
}
|
}
|
||||||
|
|
||||||
[tabindex='-1']:focus
|
[tabindex='-1']:focus
|
||||||
@ -7927,7 +7927,7 @@ button.close
|
|||||||
|
|
||||||
.bg-primary
|
.bg-primary
|
||||||
{
|
{
|
||||||
background-color: #5e72e4 !important;
|
background-color: #e27406 !important
|
||||||
}
|
}
|
||||||
|
|
||||||
a.bg-primary:hover,
|
a.bg-primary:hover,
|
||||||
|
@ -151,17 +151,25 @@
|
|||||||
var o = Math.round, r = Math.random, s = 255;
|
var o = Math.round, r = Math.random, s = 255;
|
||||||
return 'rgba(' + o(r()*s) + ',' + o(r()*s) + ',' + o(r()*s) + ',1)';
|
return 'rgba(' + o(r()*s) + ',' + o(r()*s) + ',' + o(r()*s) + ',1)';
|
||||||
}
|
}
|
||||||
var dat = JSON.parse('{{dates | tojson }}');
|
var color_idx = 1;
|
||||||
var color_idx = 0;
|
function getColor() {
|
||||||
|
const hue = color_idx * 137.508; // use golden angle approximation
|
||||||
|
if (color_idx == 10){
|
||||||
|
color_idx = 1;
|
||||||
|
} else {
|
||||||
|
color_idx += 1;
|
||||||
|
}
|
||||||
|
return `hsl(${Math.floor(hue)},100%,75%)`;
|
||||||
|
}
|
||||||
|
|
||||||
function dict2datasets(data) {
|
function dict2datasets(data) {
|
||||||
var datasets = [];
|
var datasets = [];
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
color_idx += 1;
|
|
||||||
datasets.push(
|
datasets.push(
|
||||||
{
|
{
|
||||||
label: key,
|
label: key,
|
||||||
fill: true,
|
fill: true,
|
||||||
borderColor: random_rgba(),
|
borderColor: getColor(),
|
||||||
borderSkipped: "bottom",
|
borderSkipped: "bottom",
|
||||||
borderWidth: 4,
|
borderWidth: 4,
|
||||||
borderCapStyle: 'butt',
|
borderCapStyle: 'butt',
|
||||||
@ -174,7 +182,6 @@
|
|||||||
var overall_chart_data = JSON.parse('{{overall_chart_data | tojson }}');
|
var overall_chart_data = JSON.parse('{{overall_chart_data | tojson }}');
|
||||||
var overall_chart = dict2datasets(overall_chart_data);
|
var overall_chart = dict2datasets(overall_chart_data);
|
||||||
|
|
||||||
|
|
||||||
var location_charts = {};
|
var location_charts = {};
|
||||||
var location_chart_data = JSON.parse('{{location_charts_data | tojson }}');
|
var location_chart_data = JSON.parse('{{location_charts_data | tojson }}');
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user