This commit is contained in:
Matthew Dillon 2015-10-09 19:51:40 -07:00
parent d5c58d6167
commit 1c64fca4a2
6 changed files with 163 additions and 30 deletions

View file

@ -1,39 +1,27 @@
from flask_wtf import Form
from wtforms import IntegerField, SelectField
from wtforms.validators import NumberRange, Required
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from sqlalchemy import func
from .models import Dataset, Temperature, DB
from .models import Temperature, DB
from flask import current_app
class AKIYearField(IntegerField):
def pre_validate(self, form):
if form.model.data is not None:
ymin, ymax = Temperature.query \
.with_entities(func.min(Temperature.year),
func.max(Temperature.year)) \
.filter(Temperature.dataset_id == form.model.data.id).all()[0]
self.validators = [NumberRange(min=ymin, max=ymax), Required()]
def datasets():
return Dataset.query.order_by('datatype', 'model', 'scenario')
def dataset_names(ds):
return "{0.type} ({0.resolution}) - {0.modelname} {0.scenario}".format(ds)
pass
# if form.dataset.data is not None:
# ymin, ymax = Temperature.query \
# .with_entities(func.min(Temperature.year),
# func.max(Temperature.year)) \
# .filter(Temperature.dataset_id == form.dataset.data.id).all()[0]
# self.validators = [NumberRange(min=ymin, max=ymax), Required()]
class AKIForm(Form):
community = SelectField(coerce=int,
validators=[Required(message='Please select a community')])
dataset = SelectField(validators=[Required(message='Please select a dataset')])
minyear = AKIYearField('minyear')
maxyear = AKIYearField('maxyear')
model = QuerySelectField(query_factory=datasets,
get_label=dataset_names,
allow_blank=True,
blank_text='---Select a dataset---',
validators=[Required(message='Please select a dataset')])

View file

@ -62,3 +62,35 @@ class DB:
"""
result = db.engine.execute(text(cmd), id=id).fetchall()
return result or abort(500)
@classmethod
def getDatasets(cls):
cmd = """
SELECT DISTINCT ON (
doc->'model',
doc->'datatype',
doc->'resolution',
doc->'modelname',
doc->'scenario'
)
doc->'model' AS model,
doc->'datatype' AS datatype,
doc->'resolution' AS resolution,
doc->'modelname' AS modelname,
doc->'scenario' AS scenario
FROM new_communities c,
jsonb_array_elements(c.data)
WITH ORDINALITY t1(doc, rn)
ORDER BY datatype ASC, modelname ASC, scenario ASC;
"""
result = db.engine.execute(text(cmd), id=id).fetchall()
return result or abort(500)
# WITH x AS (
# SELECT name, jsonb_array_elements(data) AS data
# FROM new_communities
# WHERE name='Anchorage')
# SELECT d.key::INTEGER AS year, d.value AS temperatures
# FROM x, jsonb_each(data) d
# WHERE data->>'model'='CRU'
# AND d.key NOT IN ('model', 'datatype', 'scenario', 'modelname', 'resolution');

View file

@ -19,7 +19,7 @@
</div>
<div class="form-group col-md-4">
<label for="modelinput">Dataset</label>
{{ render_field(form.model, class='form-control', id='modelinput') }}
{{ render_field(form.dataset, class='form-control', id='modelinput') }}
<small>Historical (1901-2009) or Projection (2001-2099)<br>
<a href="{{ url_for('main.datatypes') }}" target="_blank">
Learn more about the models and scenarios

View file

@ -70,5 +70,13 @@ def des_air_indices(indices):
def c_to_f(temp):
return (temp * 9. / 5.) + 32.
def communitiesSelect():
return [(c.id, c.name) for c in DB.getCommunities()]
def datasetsSelect():
return [("{0.model},{0.scenario}".format(d),
"{x} ({d.resolution}) - {d.modelname} {d.scenario}".format(d=d,
x=d.datatype.title()))
for d in DB.getDatasets()]

View file

@ -2,17 +2,18 @@ from numpy import arange, hstack
from flask import session, render_template, request, redirect, url_for
from flask import current_app
from . import main
from .forms import AKIForm
from .utils import getTemps, avg_air_temp, ann_air_indices, \
avg_air_indices, des_air_indices, communitiesSelect
avg_air_indices, des_air_indices, communitiesSelect, datasetsSelect
from .models import Dataset, DB
@main.route('/', methods=['GET'])
def index():
form = AKIForm()
form.community.choices = communitiesSelect()
form = generateForm()
session['community_data'] = None
session['avg_temp'] = None
session['avg_indices'] = None
@ -48,8 +49,7 @@ def index():
@main.route('/', methods=['POST'])
def index_submit():
form = AKIForm()
form.community.choices = communitiesSelect()
form = generateForm()
if form.validate():
session['community'] = request.form['community']
session['minyear'] = request.form['minyear']
@ -57,12 +57,15 @@ def index_submit():
if session['minyear'] > session['maxyear']:
session['maxyear'] = session['minyear']
session['datasets'] = request.form['model']
session['datasets'] = request.form['dataset']
current_app.logger.info(session)
return redirect(url_for('main.index'))
else:
# TODO: Fix post-POST handling
return render_template('main/index.html', form=form)
# TODO: reimport this template
@main.route('/datatypes')
def datatypes():
return render_template('main/datatypes.html')
@ -121,3 +124,10 @@ def delete():
record = request.args.get('record', '')
session['save'].pop(record)
return redirect(url_for('main.index'))
def generateForm():
form = AKIForm()
form.community.choices = communitiesSelect()
form.dataset.choices = datasetsSelect()
return form