From c58aacc502ae8d84ecbd78dfbe116fc4a1ce83ad Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 13 Apr 2017 18:09:07 -0500 Subject: [PATCH 1/6] adds security, changes measurement access --- development.ini | 2 +- pocwww/__init__.py | 7 +- pocwww/json.py | 30 +---- pocwww/measurements.py | 185 ++++++++++++++++++++++++++++++ pocwww/static/graphs.js | 106 +++++++++++++---- pocwww/templates/dashboard.jinja2 | 24 ++-- pocwww/view_helpers.py | 31 ----- pocwww/views.py | 36 +++++- setup.py | 1 + 9 files changed, 317 insertions(+), 105 deletions(-) create mode 100644 pocwww/measurements.py diff --git a/development.ini b/development.ini index f1e5520..8c67182 100644 --- a/development.ini +++ b/development.ini @@ -18,7 +18,7 @@ pyramid.includes = # '127.0.0.1' and '::1'. # debugtoolbar.hosts = 127.0.0.1 ::1 -mongo_uri = mongodb://localhost:27017/poc +mongo_uri = mongodb://poc_www:HenryPump1903@localhost:27017/poc # mongo_uri = mongodb://10.20.155.202:27017/poc diff --git a/pocwww/__init__.py b/pocwww/__init__.py index d696977..b3cfdb9 100644 --- a/pocwww/__init__.py +++ b/pocwww/__init__.py @@ -96,13 +96,12 @@ def main(global_config, **settings): jinja2_env.filters['datestring'] = format_dateString db_url = urlparse(settings['mongo_uri']) + config.registry.db = MongoClient( host=db_url.hostname, port=db_url.port, ) - config.registry.db.poc.users.update_one({"username": "admin"}, {"$set": {"username": "admin", "password": "l3tm31n"}}, upsert=True) - def add_db(request): db = config.registry.db[db_url.path[1:]] if db_url.username and db_url.password: @@ -112,6 +111,10 @@ def main(global_config, **settings): config.add_request_method(add_db, 'db', reify=True) config.add_static_view('static', 'static', cache_max_age=3600) + # Add login for admin user + config.registry.db.poc.authenticate(db_url.username, db_url.password) + config.registry.db.poc.users.update_one({"username": "admin"}, {"$set": {"username": "admin", "password": "l3tm31n"}}, upsert=True) + # CUSTOM JSON RENDERER prettyjson = JSON(indent=4) prettyjson.add_adapter(datetime, datetime_adapter) diff --git a/pocwww/json.py b/pocwww/json.py index d4b7f42..2819e01 100644 --- a/pocwww/json.py +++ b/pocwww/json.py @@ -2,6 +2,7 @@ from pyramid.view import view_config from .view_helpers import * from bson import json_util import requests +import pytz # JSON @@ -63,35 +64,6 @@ def json_valuesdaterange(request): return {'first_date': date_limits['first'], 'last_date': date_limits['last']} -@view_config(route_name="json_singlevaluebetween", renderer="prettyjson") -@view_config(route_name="json_singlevaluebetween_wparams", renderer="prettyjson") -def json_singlevaluebetween(request): - end = datetime.now() - try: # Attempt to get a value from the request. - end = request.matchdict['enddt'] - end = end.replace("T", " ") - end = datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ") - except KeyError: - pass - - start = end - timedelta(days=7) - try: # Attempt to get a value from the request. - start = request.matchdict['startdt'] - start = start.replace("T", " ") - start = datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ") - except KeyError: - pass - - tag_data = [] - grouped_tags = request.db['wellData'].aggregate([ - {"$match": {"tagname": request.matchdict['tagname'], 'timestamp': {'$gt': start, '$lte': end}}}, - { - '$sort': {"timestamp": 1} - } - ]) - return {'values': list(grouped_tags), 'start': start, 'end': end} - - @view_config(route_name="json_singlevaluedaterange", renderer="prettyjson") def json_singlevaluedaterange(request): date_limits = list(request.db['wellData'].aggregate([ diff --git a/pocwww/measurements.py b/pocwww/measurements.py new file mode 100644 index 0000000..f283bb8 --- /dev/null +++ b/pocwww/measurements.py @@ -0,0 +1,185 @@ +from pyramid.view import view_config +from pyramid.httpexceptions import HTTPFound +from pyramid.security import remember, forget +from datetime import datetime, timedelta +from functools import reduce +import pytz +from itertools import groupby + + +def get_date_measurements(request, d, tagname=None): + find_datetime = datetime(d.year, d.month, d.day, 0, 0, 0) + if tagname: + return list(request.db['measurements'].find({"dateStored": find_datetime, 'tagname': tagname})) + return list(request.db['measurements'].find({"dateStored": find_datetime})) + + +def expand_measurements_from_document(doc): + base_date = doc['dateStored'] + value_list = [] + values = doc['values'] + for hour in values: + for minute in values[hour]: + measurement_datetime = datetime(base_date.year, base_date.month, base_date.day, int(hour), int(minute), tzinfo=pytz.utc) + # print("{} = {}".format(measurement_datetime, values[hour][minute])) + value_list.append({'timestamp': measurement_datetime, 'tagvalue': values[hour][minute]}) + value_list.sort(key=lambda x: x['timestamp'], reverse=True) + doc['values'] = value_list + return doc + + +def get_measurements_between(request, start_datetime, end_datetime, tagname=None): + start_date = datetime(start_datetime.year, start_datetime.month, start_datetime.day, 0, 0, 0, tzinfo=pytz.utc) + end_date = datetime(end_datetime.year, end_datetime.month, end_datetime.day, 0, 0, 0, tzinfo=pytz.utc) + found_measurements = [] + if tagname: + found_measurements = list(map(expand_measurements_from_document, list(request.db['measurements'].find({"dateStored": {"$lte": end_date, "$gte": start_date}, 'tagname': tagname})))) + else: + found_measurements = list(map(expand_measurements_from_document, list(request.db['measurements'].find({"dateStored": {"$lte": end_date, "$gte": start_date}})))) + + for i in range(0, len(found_measurements)): + found_measurements[i]['values'] = list(filter(lambda x: x['timestamp'] >= start_datetime and x['timestamp'] <= end_datetime, found_measurements[i]['values'])) + return found_measurements + + +def combine_measurements(m1, m2): + new_measurement = { + "averages": [], + "totals": [], + "maxes": [], + "mins": [], + "units": m1["units"], + "values": sorted(m2['values'] + m1['values'], key=lambda x: x['timestamp'], reverse=True), + "tagname": m1["tagname"], + } + + # Average Value + try: + new_measurement['averages'] = m1['averages'] + new_measurement['averages'].append({"timestamp": m2['dateStored'], "averageValue": m2['averageValue']}) + except KeyError: + new_measurement['averages'].append({"timestamp": m1['dateStored'], "averageValue": m1['averageValue']}) + new_measurement['averages'].append({"timestamp": m2['dateStored'], "averageValue": m2['averageValue']}) + + # Total Value + try: + new_measurement['totals'] = m1['totals'] + new_measurement['totals'].append({"timestamp": m2['dateStored'], "totalValue": m2['totalValue']}) + except KeyError: + new_measurement['totals'].append({"timestamp": m1['dateStored'], "totalValue": m1['totalValue']}) + new_measurement['totals'].append({"timestamp": m2['dateStored'], "totalValue": m2['totalValue']}) + + # Max Value + try: + new_measurement['maxes'] = m1['maxes'] + new_measurement['maxes'].append({"timestamp": m2['dateStored'], "maxValue": m2['maxValue']}) + except KeyError: + new_measurement['maxes'].append({"timestamp": m1['dateStored'], "maxValue": m1['maxValue']}) + new_measurement['maxes'].append({"timestamp": m2['dateStored'], "maxValue": m2['maxValue']}) + + # Min Value + try: + new_measurement['mins'] = m1['mins'] + new_measurement['mins'].append({"timestamp": m2['dateStored'], "minValue": m2['minValue']}) + except KeyError: + new_measurement['mins'].append({"timestamp": m1['dateStored'], "minValue": m1['minValue']}) + new_measurement['mins'].append({"timestamp": m2['dateStored'], "minValue": m2['minValue']}) + + return new_measurement + + +def first_measurement(m1): + new_measurement = { + "averages": [], + "totals": [], + "maxes": [], + "mins": [], + "units": m1["units"], + "values": sorted(m1['values'], key=lambda x: x['timestamp'], reverse=True), + "tagname": m1["tagname"], + } + + # Average Value + try: + new_measurement['averages'] = m1['averages'] + except KeyError: + new_measurement['averages'].append({"timestamp": m1['dateStored'], "averageValue": m1['averageValue']}) + + # Total Value + try: + new_measurement['totals'] = m1['totals'] + except KeyError: + new_measurement['totals'].append({"timestamp": m1['dateStored'], "totalValue": m1['totalValue']}) + + # Max Value + try: + new_measurement['maxes'] = m1['maxes'] + except KeyError: + new_measurement['maxes'].append({"timestamp": m1['dateStored'], "maxValue": m1['maxValue']}) + + # Min Value + try: + new_measurement['mins'] = m1['mins'] + except KeyError: + new_measurement['mins'].append({"timestamp": m1['dateStored'], "minValue": m1['minValue']}) + + return new_measurement + + +def get_grouped_measurements_between(request, start_datetime, end_datetime, tagname=None): + data = sorted(get_measurements_between(request, start_datetime, end_datetime, tagname=tagname), key=lambda x: x['tagname']) + tag_data = {} + for k, g in groupby(data, lambda x: x['tagname']): + group = list(g) + if len(group) > 1: + tag_data[k] = reduce(combine_measurements, group) + else: + tag_data[k] = first_measurement(group[0]) + + return tag_data + + +@view_config(route_name='values_all', renderer="templates/valuesall.jinja2") +@view_config(route_name='json_values_all', renderer='prettyjson') +def values_all(request): + end = datetime.now(tz=pytz.utc) + try: # Attempt to get a value from the request. + end = request.matchdict['enddt'] + end = end.replace("T", " ") + end = pytz.utc.localize(datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ")) + except KeyError: + pass + + start = end - timedelta(days=2) + try: # Attempt to get a value from the request. + start = request.matchdict['startdt'] + start = start.replace("T", " ") + start = pytz.utc.localize(datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ")) + except KeyError: + pass + + all_values = get_grouped_measurements_between(request, start, end) + return {'navgroup': 'values', 'current_tag_values': all_values} + + +@view_config(route_name="json_singlevaluebetween", renderer="prettyjson") +@view_config(route_name="json_singlevaluebetween_wparams", renderer="prettyjson") +def json_singlevaluebetween(request): + end = datetime.now(tz=pytz.utc) + try: # Attempt to get a value from the request. + end = request.matchdict['enddt'] + end = end.replace("T", " ") + end = pytz.utc.localize(datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ")) + except KeyError: + pass + + start = end - timedelta(days=7) + try: # Attempt to get a value from the request. + start = request.matchdict['startdt'] + start = start.replace("T", " ") + start = pytz.utc.localize(datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ")) + except KeyError: + pass + + all_values = get_grouped_measurements_between(request, start, end, tagname=request.matchdict['tagname']) + return {'tag': all_values, 'start': start, 'end': end, 'tagname': request.matchdict['tagname']} diff --git a/pocwww/static/graphs.js b/pocwww/static/graphs.js index 9c3f9e7..b1aff55 100644 --- a/pocwww/static/graphs.js +++ b/pocwww/static/graphs.js @@ -130,33 +130,95 @@ function drawSingleGraph(data){ console.log("Destroying existing chart"); scatterChart.destroy(); } + + var tag = data.tag[data.tagname]; + console.log(tag); + console.log(tag.values.length); + var graph_data = []; - var values = data.values; var ctx = document.getElementById("myChart"); - var lines = ["currentValue", "maxDailyValue", "minDailyValue", "dailyAverage", "dailyTotal"]; - for (var i = 0; i < lines.length; i++){ - var baseObj = { - label: lines[i], - fill: false, - data: [], - lineTension: 0.05, - borderColor: color_scale[i % color_scale.length] - } - if (lines[i] == "dailyTotal"){ - baseObj['hidden'] = true; - } - graph_data.push(baseObj); + var color_index = 0; + + // Current Values + var currentValues = { + label: "Value", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] } - for(var i = 0; i < values.length; i++){ - for(var j = 0; j < lines.length; j++){ - var lineName = lines[j] - graph_data[lines.indexOf(lineName)].data.push({ - x: values[i].timestamp, - y: values[i][lineName] - }); - } + for (var i = 0; i < tag.values.length; i++){ + currentValues.data.push({x: tag.values.timestamp, y: tag.values.tagvalue}); } + + graph_data.push(currentValues) + color_index++; + + // Max Values + var maxValues = { + label: "Max", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.maxes.length; i++){ + maxValues.data.push({x: tag.maxes.timestamp, y: tag.maxes.maxValue}); + } + + graph_data.push(maxValues) + color_index++; + + // Min Values + var minValues = { + label: "Min", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.mins.length; i++){ + minValues.data.push({x: tag.mins.timestamp, y: tag.mins.maxValue}); + } + + graph_data.push(minValues) + color_index++; + + // Average Values + var averageValues = { + label: "Average", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.averages.length; i++){ + averageValues.data.push({x: tag.averages.timestamp, y: tag.averages.maxValue}); + } + + graph_data.push(averageValues) + color_index++; + + // Total Values + var totalValues = { + label: "Total", + fill: false, + data: [], + lineTension: 0.05, + borderColor: color_scale[color_index % color_scale.length] + } + + for (var i = 0; i < tag.totals.length; i++){ + totalValues.data.push({x: tag.totals.timestamp, y: tag.totals.maxValue}); + } + + graph_data.push(totalValues) + color_index++; + scatterChart = new Chart(ctx, { type: 'line', data: { diff --git a/pocwww/templates/dashboard.jinja2 b/pocwww/templates/dashboard.jinja2 index e5415d8..f98732e 100644 --- a/pocwww/templates/dashboard.jinja2 +++ b/pocwww/templates/dashboard.jinja2 @@ -23,11 +23,6 @@ Name Value - Timestamp - @@ -36,19 +31,18 @@ {{t._id}} - - {{t.value | round(3)}} - {{t.timestamp | datetime('short')}} - + {{t.currentValue | round(3)}} {{t.units}} {% endfor %} diff --git a/pocwww/view_helpers.py b/pocwww/view_helpers.py index 203d204..e04f860 100644 --- a/pocwww/view_helpers.py +++ b/pocwww/view_helpers.py @@ -8,37 +8,6 @@ from_zone = tz.tzutc() to_zone = tz.tzlocal() -def get_lastest_tag_values(request): - latest_tag_values = [] - latesttag_agg = request.db['wellData'].aggregate([ - { - '$sort': {"tagname": 1, "timestamp": 1} - }, - { - '$group': { - '_id': "$tagname", - 'timestamp': {'$last': "$timestamp"}, - 'value': {'$last': "$currentValue"}, - 'max': {'$last': "$maxDailyValue"}, - 'min': {'$last': "$minDailyValue"}, - 'average': {'$last': "$dailyAverage"}, - 'total': {'$last': "$dailyTotal"} - } - } - ]) - for t in latesttag_agg: - latest_tag_values.append(t) - return latest_tag_values - - -def get_latest_card(request): - try: - latest_card = list(request.db['cards'].find().sort("timestamp", -1).limit(1))[0] - return latest_card - except IndexError: - return [] - - def card_page(request): page_num = 1 try: diff --git a/pocwww/views.py b/pocwww/views.py index 9c3163e..bd69f8f 100644 --- a/pocwww/views.py +++ b/pocwww/views.py @@ -9,7 +9,33 @@ from .view_helpers import * @view_config(route_name='home', renderer='templates/dashboard.jinja2') @view_config(route_name="json_snapshot", renderer="prettyjson") def my_view(request): - return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': get_lastest_tag_values(request), 'card': get_latest_card(request)} + latest_tag_values = [] + latesttag_agg = request.db['measurements'].aggregate([ + {'$sort': {'dateStored': 1}}, + { + '$group': { + '_id': '$tagname', + 'currentValue': {'$last': '$currentValue'}, + 'units': {'$last': '$units'}, + 'maxValue': {'$last': '$maxValue'}, + 'minValue': {'$last': '$minValue'}, + 'totalValue': {'$last': '$totalValue'}, + 'averageValue': {'$last': '$averageValue'}, + 'useTotal': {'$last': '$useTotal'}, + 'useAverage': {'$last': '$useAverage'} + } + } + ]) + for t in latesttag_agg: + latest_tag_values.append(t) + + latest_card = [] + try: + latest_card = list(request.db['cards'].find().sort("timestamp", -1).limit(1))[0] + except IndexError: + latest_card = [] + + return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': latest_tag_values, 'card': latest_card} @view_config(route_name='cards', renderer='templates/datelist.jinja2') @@ -48,10 +74,10 @@ def card_single(request): return {"card": card, 'navgroup': 'cards', 'datelist': get_all_dates_with_cards(request), 'date': carddate, 'datepage': page_num} -@view_config(route_name='values_all', renderer="templates/valuesall.jinja2") -@view_config(route_name='json_values_all', renderer='prettyjson') -def values_all(request): - return {'navgroup': 'values', 'current_tag_values': get_lastest_tag_values(request)} +# @view_config(route_name='values_all', renderer="templates/valuesall.jinja2") +# @view_config(route_name='json_values_all', renderer='prettyjson') +# def values_all(request): +# return {'navgroup': 'values', 'current_tag_values': get_lastest_tag_values(request)} @view_config(route_name="values_tag", renderer="templates/values_single.jinja2") diff --git a/setup.py b/setup.py index dc0377d..3a78dd3 100644 --- a/setup.py +++ b/setup.py @@ -17,6 +17,7 @@ requires = [ 'requests', 'passlib', 'python-dateutil', + 'pytz', ] tests_require = [ From 9c84de53c44739312f41b7bec3f70b3a79599df5 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 17 Apr 2017 11:12:38 -0500 Subject: [PATCH 2/6] Alters measurement function to use more efficient data structure --- pocwww/json.py | 65 ------------------ pocwww/measurements.py | 94 ++++++++++++++++++++++++++- pocwww/static/graphs.js | 34 ++++++---- pocwww/templates/values_single.jinja2 | 2 + pocwww/templates/valuesall.jinja2 | 14 ++-- 5 files changed, 122 insertions(+), 87 deletions(-) diff --git a/pocwww/json.py b/pocwww/json.py index 2819e01..8686bbf 100644 --- a/pocwww/json.py +++ b/pocwww/json.py @@ -11,71 +11,6 @@ def json_lastcard(request): return get_latest_card(request) -@view_config(route_name="json_valuesbetween", renderer="prettyjson") -@view_config(route_name="json_valuesbetween_wparams", renderer="prettyjson") -def json_valuesbetween(request): - end = datetime.now() - try: # Attempt to get a value from the request. - end = request.matchdict['enddt'] - end = end.replace("T", " ") - end = datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ") - except KeyError: - pass - - start = end - timedelta(days=2) - try: # Attempt to get a value from the request. - start = request.matchdict['startdt'] - start = start.replace("T", " ") - start = datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ") - except KeyError: - pass - - tag_data = [] - grouped_tags = request.db['wellData'].aggregate([ - { - '$match': {"timestamp": {"$gt": start, "$lte": end}} - }, - { - '$sort': {"tagname": 1, "timestamp": 1} - }, - { - '$group': { - '_id': "$tagname", - 'timestamps': {'$push': "$timestamp"}, - 'currentValues': {'$push': "$currentValue"} - } - } - ]) - - for t in grouped_tags: - tag_data.append({"tagname": t['_id'], "timestamps": list(map(lambda a: a.strftime("%Y-%m-%d %H:%M:%S.%fZ"), t['timestamps'])), "currentValues": t['currentValues']}) - return {'values': tag_data, 'start': start, 'end': end} - - -@view_config(route_name="json_valuesdaterange", renderer="prettyjson") -def json_valuesdaterange(request): - date_limits = list(request.db['wellData'].aggregate([ - {"$group": { - "_id": 'null', - "last": {"$max": "$timestamp"}, - "first": {"$min": "$timestamp"} - }} - ]))[0] - return {'first_date': date_limits['first'], 'last_date': date_limits['last']} - - -@view_config(route_name="json_singlevaluedaterange", renderer="prettyjson") -def json_singlevaluedaterange(request): - date_limits = list(request.db['wellData'].aggregate([ - {"$match": {"tagname": request.matchdict['tagname']}}, - {"$group": { - "_id": 'null', - "last": {"$max": "$timestamp"}, - "first": {"$min": "$timestamp"} - }} - ]))[0] - return {'first_date': date_limits['first'], 'last_date': date_limits['last']} - @view_config(route_name="json_runstatusnow", renderer="prettyjson") def json_runstatusnow(request): diff --git a/pocwww/measurements.py b/pocwww/measurements.py index f283bb8..7442db5 100644 --- a/pocwww/measurements.py +++ b/pocwww/measurements.py @@ -140,6 +140,30 @@ def get_grouped_measurements_between(request, start_datetime, end_datetime, tagn @view_config(route_name='values_all', renderer="templates/valuesall.jinja2") +def values_page(request): + latest_tag_values = [] + latesttag_agg = request.db['measurements'].aggregate([ + {'$sort': {'dateStored': 1}}, + { + '$group': { + '_id': '$tagname', + 'currentValue': {'$last': '$currentValue'}, + 'units': {'$last': '$units'}, + 'maxValue': {'$last': '$maxValue'}, + 'minValue': {'$last': '$minValue'}, + 'totalValue': {'$last': '$totalValue'}, + 'averageValue': {'$last': '$averageValue'}, + 'useTotal': {'$last': '$useTotal'}, + 'useAverage': {'$last': '$useAverage'} + } + } + ]) + for t in latesttag_agg: + latest_tag_values.append(t) + + return {'navgroup': 'values', "current_values": latest_tag_values} + + @view_config(route_name='json_values_all', renderer='prettyjson') def values_all(request): end = datetime.now(tz=pytz.utc) @@ -158,8 +182,28 @@ def values_all(request): except KeyError: pass + latest_tag_values = [] + latesttag_agg = request.db['measurements'].aggregate([ + {'$sort': {'dateStored': 1}}, + { + '$group': { + '_id': '$tagname', + 'currentValue': {'$last': '$currentValue'}, + 'units': {'$last': '$units'}, + 'maxValue': {'$last': '$maxValue'}, + 'minValue': {'$last': '$minValue'}, + 'totalValue': {'$last': '$totalValue'}, + 'averageValue': {'$last': '$averageValue'}, + 'useTotal': {'$last': '$useTotal'}, + 'useAverage': {'$last': '$useAverage'} + } + } + ]) + for t in latesttag_agg: + latest_tag_values.append(t) + all_values = get_grouped_measurements_between(request, start, end) - return {'navgroup': 'values', 'current_tag_values': all_values} + return {'navgroup': 'values', 'values': all_values, "current_values": latest_tag_values} @view_config(route_name="json_singlevaluebetween", renderer="prettyjson") @@ -183,3 +227,51 @@ def json_singlevaluebetween(request): all_values = get_grouped_measurements_between(request, start, end, tagname=request.matchdict['tagname']) return {'tag': all_values, 'start': start, 'end': end, 'tagname': request.matchdict['tagname']} + + +@view_config(route_name="json_valuesbetween", renderer="prettyjson") +@view_config(route_name="json_valuesbetween_wparams", renderer="prettyjson") +def json_valuesbetween(request): + end = datetime.now(tz=pytz.utc) + try: # Attempt to get a value from the request. + end = request.matchdict['enddt'] + end = end.replace("T", " ") + end = pytz.utc.localize(datetime.strptime(end, "%Y-%m-%d %H:%M:%S.%fZ")) + except KeyError: + pass + + start = end - timedelta(days=2) + try: # Attempt to get a value from the request. + start = request.matchdict['startdt'] + start = start.replace("T", " ") + start = pytz.utc.localize(datetime.strptime(start, "%Y-%m-%d %H:%M:%S.%fZ")) + except KeyError: + pass + + tag_data = get_grouped_measurements_between(request, start, end) + return {'values': tag_data, 'start': start, 'end': end} + + +@view_config(route_name="json_valuesdaterange", renderer="prettyjson") +def json_valuesdaterange(request): + date_limits = list(request.db['measurements'].aggregate([ + {"$group": { + "_id": 'null', + "last": {"$max": "$dateStored"}, + "first": {"$min": "$dateStored"} + }} + ]))[0] + return {'first_date': date_limits['first'], 'last_date': date_limits['last']} + + +@view_config(route_name="json_singlevaluedaterange", renderer="prettyjson") +def json_singlevaluedaterange(request): + date_limits = list(request.db['measurements'].aggregate([ + {"$match": {"tagname": request.matchdict['tagname']}}, + {"$group": { + "_id": 'null', + "last": {"$max": "$dateStored"}, + "first": {"$min": "$dateStored"} + }} + ]))[0] + return {'first_date': date_limits['first'], 'last_date': date_limits['last']} diff --git a/pocwww/static/graphs.js b/pocwww/static/graphs.js index b1aff55..9a47fe6 100644 --- a/pocwww/static/graphs.js +++ b/pocwww/static/graphs.js @@ -86,23 +86,30 @@ function drawChart(data){ var graph_data = [] ; var json_data = data.values; var ctx = document.getElementById("valueChart"); - for (var i = 0; i < json_data.length; i++){ + + var color_index = 0; + + for (x in data.values){ + var tagdata = data.values[x]; var newObj = { - label: json_data[i].tagname, + label: x, fill: false, data: [], lineTension: 0.05, - borderColor: color_scale[i % color_scale.length], + borderColor: color_scale[color_index % color_scale.length], pointRadius: 2 - } - for(var j = 0; j < json_data[i].timestamps.length; j++){ + }; + + for (var j = 0; j < tagdata.values.length; j++){ newObj.data.push({ - x: json_data[i].timestamps[j], - y: json_data[i].currentValues[j] + x: tagdata.values[j].timestamp, + y: tagdata.values[j].tagvalue }); } graph_data.push(newObj); + color_index++; } + scatterChart = new Chart(ctx, { type: 'line', responsive: true, @@ -133,7 +140,6 @@ function drawSingleGraph(data){ var tag = data.tag[data.tagname]; console.log(tag); - console.log(tag.values.length); var graph_data = []; var ctx = document.getElementById("myChart"); @@ -149,7 +155,7 @@ function drawSingleGraph(data){ } for (var i = 0; i < tag.values.length; i++){ - currentValues.data.push({x: tag.values.timestamp, y: tag.values.tagvalue}); + currentValues.data.push({x: tag.values[i].timestamp, y: tag.values[i].tagvalue}); } graph_data.push(currentValues) @@ -165,7 +171,7 @@ function drawSingleGraph(data){ } for (var i = 0; i < tag.maxes.length; i++){ - maxValues.data.push({x: tag.maxes.timestamp, y: tag.maxes.maxValue}); + maxValues.data.push({x: tag.maxes[i].timestamp, y: tag.maxes[i].maxValue}); } graph_data.push(maxValues) @@ -181,7 +187,7 @@ function drawSingleGraph(data){ } for (var i = 0; i < tag.mins.length; i++){ - minValues.data.push({x: tag.mins.timestamp, y: tag.mins.maxValue}); + minValues.data.push({x: tag.mins[i].timestamp, y: tag.mins[i].maxValue}); } graph_data.push(minValues) @@ -197,7 +203,7 @@ function drawSingleGraph(data){ } for (var i = 0; i < tag.averages.length; i++){ - averageValues.data.push({x: tag.averages.timestamp, y: tag.averages.maxValue}); + averageValues.data.push({x: tag.averages[i].timestamp, y: tag.averages[i].maxValue}); } graph_data.push(averageValues) @@ -213,12 +219,14 @@ function drawSingleGraph(data){ } for (var i = 0; i < tag.totals.length; i++){ - totalValues.data.push({x: tag.totals.timestamp, y: tag.totals.maxValue}); + totalValues.data.push({x: tag.totals[i].timestamp, y: tag.totals[i].maxValue}); } graph_data.push(totalValues) color_index++; + console.log(graph_data); + scatterChart = new Chart(ctx, { type: 'line', data: { diff --git a/pocwww/templates/values_single.jinja2 b/pocwww/templates/values_single.jinja2 index 8012303..449bdb9 100644 --- a/pocwww/templates/values_single.jinja2 +++ b/pocwww/templates/values_single.jinja2 @@ -47,6 +47,8 @@ $.ajax({ success: drawSingleSlider }); +console.log("/json/values/tag/" + tagName + "/between/" + start + "/" + end); + $.ajax({ dataType: 'json', url: "/json/values/tag/" + tagName + "/between/" + start + "/" + end, diff --git a/pocwww/templates/valuesall.jinja2 b/pocwww/templates/valuesall.jinja2 index 6ef108a..938258a 100644 --- a/pocwww/templates/valuesall.jinja2 +++ b/pocwww/templates/valuesall.jinja2 @@ -15,19 +15,17 @@ Min Average Total - Last Stored - {% for t in current_tag_values %} + {% for t in current_values %} {{t._id}} - {{t.value | round(3)}} - {{t.max | round(3)}} - {{t.min | round(3)}} - {{t.average | round(3)}} - {{t.total | round(3)}} - {{t.timestamp | datetime('medium')}} + {{t.currentValue | round(3)}} {{t.units}} + {{t.maxValue | round(3)}} {{t.units}} + {{t.minValue | round(3)}} {{t.units}} + {% if t.useAverage %}{{t.averageValue | round(3)}} {{t.units}}{% endif %} + {% if t.useTotal %}{{t.totalValue | round(3)}} {{t.units}}{% endif %} {% endfor %} From 6c41beb1b0da6d88beb50009c85409adebcbc566 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Wed, 19 Apr 2017 16:03:35 -0500 Subject: [PATCH 3/6] Starts splitting views/json routes into separate files --- pocwww/__init__.py | 52 +++++++++++++++++------------------ pocwww/cards.py | 43 +++++++++++++++++++++++++++++ pocwww/fluid_shots.py | 9 ++++++ pocwww/json.py | 8 ------ pocwww/measurements.py | 21 ++++++++------ pocwww/views.py | 62 ------------------------------------------ pocwww/well_tests.py | 9 ++++++ 7 files changed, 99 insertions(+), 105 deletions(-) create mode 100644 pocwww/cards.py create mode 100644 pocwww/fluid_shots.py create mode 100644 pocwww/well_tests.py diff --git a/pocwww/__init__.py b/pocwww/__init__.py index b3cfdb9..4afa9f8 100644 --- a/pocwww/__init__.py +++ b/pocwww/__init__.py @@ -126,72 +126,70 @@ def main(global_config, **settings): # SHARED ROUTES config.add_route('home', '/') config.add_route('json_snapshot', '/json') + config.add_route("json_users", "/json/users", factory='pocwww.security.UserLoginFactory') + # Cards config.add_route('cards_page', '/cards/{cards_date}/{page_num}') config.add_route('json_cards_page', '/json/cards/{cards_date}/{page_num}') config.add_route('cards_date', '/cards/{cards_date}') config.add_route('json_cards_date', '/json/cards/{cards_date}') - config.add_route('cards', '/cards') config.add_route('json_cards', '/json/cards') - config.add_route('card_single', "/card/view/{stroke_number}") config.add_route('json_card_single', "/json/card/view/{stroke_number}") + config.add_route('json_lastcard', "/json/lastcard") - config.add_route('values_all', "/values") - config.add_route('json_values_all', "/json/values") - - config.add_route('values_tag', "/values/tag/{tagname}") - - config.add_route('values_time', '/values/time/{time}') - config.add_route('json_values_time', '/json/values/time/{time}') + # Measurements + config.add_route('measurements_all', "/values") + config.add_route('measurements_all_json', "/json/values") + config.add_route('measurements_between_wparams_json', "/json/values/between/{startdt}/{enddt}") + config.add_route('measurements_between_json', "/json/values/between") + config.add_route("measurements_daterange_json", "/json/values/daterange") + config.add_route('measurements_singlebetween_wparams_json', "/json/values/tag/{tagname}/between/{startdt}/{enddt}") + config.add_route('measurements_singlebetween_json', "/json/values/tag/{tagname}") + config.add_route("measurements_singledaterange_json", "/json/values/tag/{tagname}/daterange") + config.add_route('measurements_single', "/values/tag/{tagname}") + # Gauge Off config.add_route('gaugeoff_all', '/gaugeoff') config.add_route('json_gaugeoff_all', '/json/gaugeoff') + # Fluid Shots config.add_route('fluidshots_all', '/fluidshots') config.add_route('json_fluidshots_all', '/json/fluidshots') + # Well Tests config.add_route('welltests_all', '/welltests') config.add_route('json_welltests_all', '/json/welltests') + # Run Status config.add_route('runstatus', '/runstatus') config.add_route('json_runstatus_page', '/json/runstatus/{page_num}') config.add_route('json_runstatus', '/json/runstatus') + config.add_route('json_runstatusnow', "/json/runstatusnow") + # Configuration config.add_route('json_config', '/json/config', factory='pocwww.security.UserLoginFactory') config.add_route('config', '/config', factory='pocwww.security.UserLoginFactory') + # Setpoints config.add_route('json_setpoints', '/json/setpoints', factory='pocwww.security.UserLoginFactory') config.add_route('json_mode', '/json/mode', factory='pocwww.security.UserLoginFactory') config.add_route('setpoints', '/setpoints', factory='pocwww.security.UserLoginFactory') + # Administration config.add_route('admin', '/admin', factory='pocwww.security.UserLoginFactory') config.add_route('auth', '/sign/{action}') config.add_route('register', '/register', factory='pocwww.security.UserLoginFactory') - # JSON-ONLY ROUTES - config.add_route('json_lastcard', "/json/lastcard") - config.add_route('json_runstatusnow', "/json/runstatusnow") - - config.add_route('json_valuesbetween_wparams', "/json/values/between/{startdt}/{enddt}") - config.add_route('json_valuesbetween', "/json/values/between") - config.add_route("json_valuesdaterange", "/json/values/daterange") - - config.add_route('json_singlevaluebetween_wparams', "/json/values/tag/{tagname}/between/{startdt}/{enddt}") - config.add_route('json_singlevaluebetween', "/json/values/tag/{tagname}") - config.add_route("json_singlevaluedaterange", "/json/values/tag/{tagname}/daterange") - + # POC Interface config.add_route("json_updateconfig", "/json/updateconfig", factory='pocwww.security.UserLoginFactory') - config.add_route("json_shake", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') config.add_route("json_cmd", '/json/cmd/{action}', factory='pocwww.security.UserLoginFactory') - - # config.add_route("json_cmd_start", "/json/cmd/start", factory='pocwww.security.UserLoginFactory') - # config.add_route("json_cmd_stop", "/json/cmd/stop", factory='pocwww.security.UserLoginFactory') - # config.add_route("json_cmd_shake", "/json/cmd/shake", factory='pocwww.security.UserLoginFactory') config.add_route("json_update_poc_address", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory') + config.add_route("json_shake", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') + + - config.add_route("json_users", "/json/users", factory='pocwww.security.UserLoginFactory') config.scan() return config.make_wsgi_app() diff --git a/pocwww/cards.py b/pocwww/cards.py new file mode 100644 index 0000000..c6ff0e1 --- /dev/null +++ b/pocwww/cards.py @@ -0,0 +1,43 @@ +from pyramid.view import view_config +from .view_helpers import * + + +@view_config(route_name="json_lastcard", renderer="prettyjson") +def json_lastcard(request): + return get_latest_card(request) + + +@view_config(route_name='cards', renderer='templates/datelist.jinja2') +@view_config(route_name='json_cards', renderer='prettyjson') +def cards(request): + return {'datelist': get_all_dates_with_cards(request), 'navgroup': 'cards'} + + +@view_config(route_name='cards_page', renderer='templates/cardlist.jinja2') +@view_config(route_name='cards_date', renderer='templates/cardlist.jinja2') +@view_config(route_name='json_cards_date', renderer='prettyjson') +@view_config(route_name='json_cards_page', renderer='prettyjson') +def cards_page(request): + cp = card_page(request) + cp['datelist'] = get_all_dates_with_cards(request) + return cp + + +@view_config(route_name='card_single', renderer='templates/cardsingle.jinja2') +@view_config(route_name='json_card_single', renderer='prettyjson') +def card_single(request): + card = {} + try: + card = list(request.db['cards'].find({"strokeNumber": int(request.matchdict['stroke_number'])}))[0] + except IndexError: + pass + + datepage_url = request.referrer.split("/")[3:] + page_num = 1 + carddate = "" + if len(datepage_url) > 2: + page_num = int(datepage_url[2]) + if len(datepage_url) > 1: + carddate = datepage_url[1] + + return {"card": card, 'navgroup': 'cards', 'datelist': get_all_dates_with_cards(request), 'date': carddate, 'datepage': page_num} diff --git a/pocwww/fluid_shots.py b/pocwww/fluid_shots.py new file mode 100644 index 0000000..203be11 --- /dev/null +++ b/pocwww/fluid_shots.py @@ -0,0 +1,9 @@ +from pyramid.view import view_config +from .view_helpers import * + + +@view_config(route_name="fluidshots_all", renderer="templates/fluidshots.jinja2") +@view_config(route_name="json_fluidshots_all", renderer="prettyjson") +def fluidshots_all(request): + fluidshots = list(request.db['fluidShots'].find()) + return {'navgroup': 'fluidshots', 'data': fluidshots} diff --git a/pocwww/json.py b/pocwww/json.py index 8686bbf..4f63a3c 100644 --- a/pocwww/json.py +++ b/pocwww/json.py @@ -4,14 +4,6 @@ from bson import json_util import requests import pytz - -# JSON -@view_config(route_name="json_lastcard", renderer="prettyjson") -def json_lastcard(request): - return get_latest_card(request) - - - @view_config(route_name="json_runstatusnow", renderer="prettyjson") def json_runstatusnow(request): status = False diff --git a/pocwww/measurements.py b/pocwww/measurements.py index 7442db5..c2778c7 100644 --- a/pocwww/measurements.py +++ b/pocwww/measurements.py @@ -139,7 +139,7 @@ def get_grouped_measurements_between(request, start_datetime, end_datetime, tagn return tag_data -@view_config(route_name='values_all', renderer="templates/valuesall.jinja2") +@view_config(route_name='measurements_all', renderer="templates/valuesall.jinja2") def values_page(request): latest_tag_values = [] latesttag_agg = request.db['measurements'].aggregate([ @@ -164,7 +164,7 @@ def values_page(request): return {'navgroup': 'values', "current_values": latest_tag_values} -@view_config(route_name='json_values_all', renderer='prettyjson') +@view_config(route_name='measurements_all_json', renderer='prettyjson') def values_all(request): end = datetime.now(tz=pytz.utc) try: # Attempt to get a value from the request. @@ -206,8 +206,8 @@ def values_all(request): return {'navgroup': 'values', 'values': all_values, "current_values": latest_tag_values} -@view_config(route_name="json_singlevaluebetween", renderer="prettyjson") -@view_config(route_name="json_singlevaluebetween_wparams", renderer="prettyjson") +@view_config(route_name="measurements_singlebetween_json", renderer="prettyjson") +@view_config(route_name="measurements_singlebetween_wparams_json", renderer="prettyjson") def json_singlevaluebetween(request): end = datetime.now(tz=pytz.utc) try: # Attempt to get a value from the request. @@ -229,8 +229,8 @@ def json_singlevaluebetween(request): return {'tag': all_values, 'start': start, 'end': end, 'tagname': request.matchdict['tagname']} -@view_config(route_name="json_valuesbetween", renderer="prettyjson") -@view_config(route_name="json_valuesbetween_wparams", renderer="prettyjson") +@view_config(route_name="measurements_between_json", renderer="prettyjson") +@view_config(route_name="measurements_between_wparams_json", renderer="prettyjson") def json_valuesbetween(request): end = datetime.now(tz=pytz.utc) try: # Attempt to get a value from the request. @@ -252,7 +252,7 @@ def json_valuesbetween(request): return {'values': tag_data, 'start': start, 'end': end} -@view_config(route_name="json_valuesdaterange", renderer="prettyjson") +@view_config(route_name="measurements_daterange_json", renderer="prettyjson") def json_valuesdaterange(request): date_limits = list(request.db['measurements'].aggregate([ {"$group": { @@ -264,7 +264,7 @@ def json_valuesdaterange(request): return {'first_date': date_limits['first'], 'last_date': date_limits['last']} -@view_config(route_name="json_singlevaluedaterange", renderer="prettyjson") +@view_config(route_name="measurements_singledaterange_json", renderer="prettyjson") def json_singlevaluedaterange(request): date_limits = list(request.db['measurements'].aggregate([ {"$match": {"tagname": request.matchdict['tagname']}}, @@ -275,3 +275,8 @@ def json_singlevaluedaterange(request): }} ]))[0] return {'first_date': date_limits['first'], 'last_date': date_limits['last']} + +@view_config(route_name="measurements_single", renderer="templates/values_single.jinja2") +def measurements_single(request): + tagname = request.matchdict['tagname'] + return {'navgroup': 'values', 'tagname': tagname} diff --git a/pocwww/views.py b/pocwww/views.py index bd69f8f..906fc9d 100644 --- a/pocwww/views.py +++ b/pocwww/views.py @@ -38,54 +38,6 @@ def my_view(request): return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': latest_tag_values, 'card': latest_card} -@view_config(route_name='cards', renderer='templates/datelist.jinja2') -@view_config(route_name='json_cards', renderer='prettyjson') -def cards(request): - return {'datelist': get_all_dates_with_cards(request), 'navgroup': 'cards'} - - -@view_config(route_name='cards_page', renderer='templates/cardlist.jinja2') -@view_config(route_name='cards_date', renderer='templates/cardlist.jinja2') -@view_config(route_name='json_cards_date', renderer='prettyjson') -@view_config(route_name='json_cards_page', renderer='prettyjson') -def cards_page(request): - cp = card_page(request) - cp['datelist'] = get_all_dates_with_cards(request) - return cp - - -@view_config(route_name='card_single', renderer='templates/cardsingle.jinja2') -@view_config(route_name='json_card_single', renderer='prettyjson') -def card_single(request): - card = {} - try: - card = list(request.db['cards'].find({"strokeNumber": int(request.matchdict['stroke_number'])}))[0] - except IndexError: - pass - - datepage_url = request.referrer.split("/")[3:] - page_num = 1 - carddate = "" - if len(datepage_url) > 2: - page_num = int(datepage_url[2]) - if len(datepage_url) > 1: - carddate = datepage_url[1] - - return {"card": card, 'navgroup': 'cards', 'datelist': get_all_dates_with_cards(request), 'date': carddate, 'datepage': page_num} - - -# @view_config(route_name='values_all', renderer="templates/valuesall.jinja2") -# @view_config(route_name='json_values_all', renderer='prettyjson') -# def values_all(request): -# return {'navgroup': 'values', 'current_tag_values': get_lastest_tag_values(request)} - - -@view_config(route_name="values_tag", renderer="templates/values_single.jinja2") -def values_tag(request): - tagname = request.matchdict['tagname'] - return {'navgroup': 'values', 'tagname': tagname} - - @view_config(route_name="gaugeoff_all", renderer="templates/gaugeoff_all.jinja2") @view_config(route_name="json_gaugeoff_all", renderer="prettyjson") def gaugeoff_all(request): @@ -130,20 +82,6 @@ def gaugeoff_all(request): return {'navgroup': 'gaugeoff', 'data': gaugeoff_list} -@view_config(route_name="fluidshots_all", renderer="templates/fluidshots.jinja2") -@view_config(route_name="json_fluidshots_all", renderer="prettyjson") -def fluidshots_all(request): - fluidshots = list(request.db['fluidShots'].find()) - return {'navgroup': 'fluidshots', 'data': fluidshots} - - -@view_config(route_name="welltests_all", renderer="templates/welltests.jinja2") -@view_config(route_name="json_welltests_all", renderer="prettyjson") -def welltests_all(request): - welltests = list(request.db['wellTests'].find()) - return {'navgroup': 'welltests', 'data': welltests} - - @view_config(route_name="runstatus", renderer="templates/runstatus.jinja2") @view_config(route_name="json_runstatus", renderer="prettyjson") @view_config(route_name="json_runstatus_page", renderer="prettyjson") diff --git a/pocwww/well_tests.py b/pocwww/well_tests.py new file mode 100644 index 0000000..e9e47c8 --- /dev/null +++ b/pocwww/well_tests.py @@ -0,0 +1,9 @@ +from pyramid.view import view_config +from .view_helpers import * + + +@view_config(route_name="welltests_all", renderer="templates/welltests.jinja2") +@view_config(route_name="json_welltests_all", renderer="prettyjson") +def welltests_all(request): + welltests = list(request.db['wellTests'].find()) + return {'navgroup': 'welltests', 'data': welltests} From d06e6f8e633cd691e3e247fa741a587827bba3ce Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 20 Apr 2017 21:54:17 -0500 Subject: [PATCH 4/6] Updates gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4dc76a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +env/* +pocwww.egg* From 8fb95cff092867e9e248eba30cde4ddc60b7fa61 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 21 Apr 2017 15:49:20 -0500 Subject: [PATCH 5/6] Splitting functions into separate files --- pocwww/__init__.py | 2 +- pocwww/cards.py | 49 +++++++++- pocwww/fluid_shots.py | 1 - pocwww/gauge_off.py | 44 +++++++++ pocwww/{json.py => poc_interface.py} | 78 +++------------ pocwww/run_status.py | 30 ++++++ pocwww/view_helpers.py | 77 --------------- pocwww/views.py | 136 ++++++++++++++------------- pocwww/well_tests.py | 1 - 9 files changed, 203 insertions(+), 215 deletions(-) create mode 100644 pocwww/gauge_off.py rename pocwww/{json.py => poc_interface.py} (66%) create mode 100644 pocwww/run_status.py delete mode 100644 pocwww/view_helpers.py diff --git a/pocwww/__init__.py b/pocwww/__init__.py index 4afa9f8..30eb4bb 100644 --- a/pocwww/__init__.py +++ b/pocwww/__init__.py @@ -184,9 +184,9 @@ def main(global_config, **settings): # POC Interface config.add_route("json_updateconfig", "/json/updateconfig", factory='pocwww.security.UserLoginFactory') + config.add_route("json_shake", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') # Shake command is separate for allowing all access config.add_route("json_cmd", '/json/cmd/{action}', factory='pocwww.security.UserLoginFactory') config.add_route("json_update_poc_address", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory') - config.add_route("json_shake", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') diff --git a/pocwww/cards.py b/pocwww/cards.py index c6ff0e1..183c202 100644 --- a/pocwww/cards.py +++ b/pocwww/cards.py @@ -1,6 +1,24 @@ from pyramid.view import view_config -from .view_helpers import * +from .pagination import Pagination +def get_all_dates_with_cards(request): + datelist = [] + dateagg = request.db['cards'].aggregate([ + {"$group": { + "_id": {"$concat": [ + {"$substr": [{"$year": "$timestamp"}, 0, 4]}, + "-", + {"$substr": [{"$month": "$timestamp"}, 0, 2]}, + "-", + {"$substr": [{"$dayOfMonth": "$timestamp"}, 0, 2]}, + ]}, + "count": {"$sum": 1} + }}, + {"$sort": {"_id": -1}} + ]) + for d in dateagg: + datelist.append({'count': d['count'], 'date': datetime.strptime(d['_id'], "%Y-%m-%d").date()}) + return list(datelist) @view_config(route_name="json_lastcard", renderer="prettyjson") def json_lastcard(request): @@ -18,9 +36,32 @@ def cards(request): @view_config(route_name='json_cards_date', renderer='prettyjson') @view_config(route_name='json_cards_page', renderer='prettyjson') def cards_page(request): - cp = card_page(request) - cp['datelist'] = get_all_dates_with_cards(request) - return cp + page_num = 1 + try: + page_num = int(request.matchdict['page_num']) + except KeyError: + pass + + cards_date_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + try: + cards_date_start = datetime.strptime(request.matchdict['cards_date'], "%Y-%m-%d") + except KeyError: + pass + + cards_date_end = cards_date_start + timedelta(days=1) + + num_per_page = 100 + num_cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).count() + pages = ceil(num_cards / num_per_page) + + cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page) + + return { + 'cards': list(cards), + 'pagination': Pagination(page_num, num_per_page, num_cards), + 'cards_date': cards_date_start.strftime("%Y-%m-%d"), 'navgroup': 'cards', + 'datelist': get_all_dates_with_cards(request) + } @view_config(route_name='card_single', renderer='templates/cardsingle.jinja2') diff --git a/pocwww/fluid_shots.py b/pocwww/fluid_shots.py index 203be11..3698990 100644 --- a/pocwww/fluid_shots.py +++ b/pocwww/fluid_shots.py @@ -1,5 +1,4 @@ from pyramid.view import view_config -from .view_helpers import * @view_config(route_name="fluidshots_all", renderer="templates/fluidshots.jinja2") diff --git a/pocwww/gauge_off.py b/pocwww/gauge_off.py new file mode 100644 index 0000000..a5a19b1 --- /dev/null +++ b/pocwww/gauge_off.py @@ -0,0 +1,44 @@ +from pyramid.view import view_config + +@view_config(route_name="gaugeoff_all", renderer="templates/gaugeoff_all.jinja2") +@view_config(route_name="json_gaugeoff_all", renderer="prettyjson") +def gaugeoff_all(request): + gaugeoff_list = [] + dateagg = list(request.db['gaugeOff'].aggregate( + [ + { + '$project': { + 'yearMonthDay': {'$dateToString': {'format': "%Y-%m-%d", 'date': "$timestamp"}}, + 'tagname': 1, + 'dailyTotal': 1, + 'dailyAverage': 1, + 'maxDailyValue': 1, + 'minDailyValue': 1, + 'currentValue': 1 + } + }, + { + '$group': { + '_id': "$yearMonthDay", + 'tags': {'$push': {'name': "$tagname"}}, + 'totals': {'$push': {'total': "$dailyTotal"}}, + 'averages': {'$push': {'average': "$dailyAverage"}}, + 'max': {'$push': {'max': "$maxDailyValue"}}, + 'min': {'$push': {'min': "$minDailyValue"}}, + 'last': {'$push': {'last': "$currentValue"}} + } + } + ])) + for d in dateagg: + newGO = {'date': datetime.strptime(d["_id"], '%Y-%m-%d'), 'tags': {}} + for i in range(0, len(d['tags'])): + newTagObj = { + "max": d['max'][i]['max'], + "min": d['min'][i]['min'], + "last": d['last'][i]['last'], + "total": d['totals'][i]['total'], + "average": d['averages'][i]['average'], + } + newGO['tags'][d['tags'][i]['name']] = newTagObj + gaugeoff_list.append(newGO) + return {'navgroup': 'gaugeoff', 'data': gaugeoff_list} diff --git a/pocwww/json.py b/pocwww/poc_interface.py similarity index 66% rename from pocwww/json.py rename to pocwww/poc_interface.py index 4f63a3c..2f3da7c 100644 --- a/pocwww/json.py +++ b/pocwww/poc_interface.py @@ -1,18 +1,13 @@ from pyramid.view import view_config -from .view_helpers import * -from bson import json_util import requests -import pytz +from datetime import datetime -@view_config(route_name="json_runstatusnow", renderer="prettyjson") -def json_runstatusnow(request): - status = False - try: - status = list(request.db['runStatus'].find().sort("timestamp", -1).limit(1))[0] - except IndexError: - pass - - return {'runstatus': status} +def get_poc_address(request): + addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"})) + address = False + if len(addr_obj) > 0: + address = addr_obj[0]['pocIPAddress'] + return address @view_config(route_name="json_updateconfig", renderer="prettyjson", request_method='POST', permission="edit") @@ -61,13 +56,14 @@ def json_updateconfig(request): @view_config(route_name="json_cmd", renderer="prettyjson", permission="edit") def json_cmd(request): + print("got here") action = request.matchdict['action'] address = get_poc_address(request) or 'localhost' java_url = {} java_url['start'] = "http://{}:8000/command?cmd=start&user={}".format(address, request.authenticated_userid) java_url['stop'] = "http://{}:8000/command?cmd=stop&user={}".format(address, request.authenticated_userid) - java_url['shake'] = "http://{}:8000/shake".format(address) + # java_url['shake'] = "http://{}:8000/shake".format(address) r = requests.get(java_url[action]) return r.text if r.status_code == 200 else {"status": "failure sending command"} @@ -92,59 +88,9 @@ def json_update_poc_address(request): return {"status": "failure"} -@view_config(route_name="json_users", renderer="prettyjson", request_method='POST', permission="edit") -def json_newuser(request): - jsb = request.json_body - if request.db['users'].count({"username": jsb['username']}) > 0: - fail_reason = "There is already a user with this username" - return {"status": 'fail', "info": fail_reason} - - elif len(jsb['username']) < 5: - fail_reason = "The username must be at least 5 characters" - return {"status": 'fail', "info": fail_reason} - - elif len(jsb['password']) < 5: - fail_reason = "The password must be at least 5 characters" - return {"status": 'fail', "info": fail_reason} - - else: - set_return = set_password(request, jsb['username'], jsb['password']) - return {'status': "OK"} - - -@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='GET') -def json_getuser(request): - user_list = [] - users = list(request.db['users'].find()) - for user in users: - user_list.append(user['username']) - return {'users': user_list} - - -@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='DELETE') -def json_deleteuser(request): - request.db['users'].remove({'username': request.json_body['username']}) - user_list = [] - users = list(request.db['users'].find()) - for user in users: - user_list.append(user['username']) - return {'users': user_list} - - -@view_config(route_name="json_users", renderer="prettyjson", request_method='PUT', permission="edit") -def json_updateuser(request): - jsb = request.json_body - if len(jsb['username']) < 5: - fail_reason = "The username must be at least 5 characters" - return {"status": 'fail', "info": fail_reason} - - elif len(jsb['password']) < 5: - fail_reason = "The password must be at least 5 characters" - return {"status": 'fail', "info": fail_reason} - - else: - set_return = set_password(request, jsb['username'], jsb['password']) - return {'status': "OK"} +@view_config(route_name='setpoints', renderer='templates/setpoints.jinja2', permission='edit') +def setpoints(request): + return {"navgroup": "setpoints"} @view_config(route_name="json_setpoints", renderer="prettyjson", request_method='GET', permission='edit') diff --git a/pocwww/run_status.py b/pocwww/run_status.py new file mode 100644 index 0000000..cd35e6e --- /dev/null +++ b/pocwww/run_status.py @@ -0,0 +1,30 @@ +from pyramid.view import view_config +from math import ceil +from .pagination import Pagination + +@view_config(route_name="runstatus", renderer="templates/runstatus.jinja2") +@view_config(route_name="json_runstatus", renderer="prettyjson") +@view_config(route_name="json_runstatus_page", renderer="prettyjson") +def run_status(request): + page_num = 1 + try: + page_num = int(request.matchdict['page_num']) + except KeyError: + pass + + num_per_page = 100 + num_cards = request.db['runStatus'].count() + pages = ceil(num_cards / num_per_page) + runStatuses = list(request.db['runStatus'].find().sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page)) + return {'navgroup': 'runstatus', 'data': runStatuses, 'pagination': Pagination(page_num, num_per_page, num_cards)} + + +@view_config(route_name="json_runstatusnow", renderer="prettyjson") +def json_runstatusnow(request): + status = False + try: + status = list(request.db['runStatus'].find().sort("timestamp", -1).limit(1))[0] + except IndexError: + pass + + return {'runstatus': status} diff --git a/pocwww/view_helpers.py b/pocwww/view_helpers.py deleted file mode 100644 index e04f860..0000000 --- a/pocwww/view_helpers.py +++ /dev/null @@ -1,77 +0,0 @@ -from datetime import datetime, timedelta -from math import ceil -from passlib.apps import custom_app_context as poc_pwd_context -from dateutil import tz -from .pagination import Pagination - -from_zone = tz.tzutc() -to_zone = tz.tzlocal() - - -def card_page(request): - page_num = 1 - try: - page_num = int(request.matchdict['page_num']) - except KeyError: - pass - - cards_date_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) - try: - cards_date_start = datetime.strptime(request.matchdict['cards_date'], "%Y-%m-%d") - except KeyError: - pass - - cards_date_end = cards_date_start + timedelta(days=1) - - num_per_page = 100 - num_cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).count() - pages = ceil(num_cards / num_per_page) - - cards = request.db['cards'].find({'timestamp': {'$lt': cards_date_end, '$gte': cards_date_start}}).sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page) - return {'cards': list(cards), 'pagination': Pagination(page_num, num_per_page, num_cards), 'cards_date': cards_date_start.strftime("%Y-%m-%d"), 'navgroup': 'cards'} - - -def get_all_dates_with_cards(request): - datelist = [] - dateagg = request.db['cards'].aggregate([ - {"$group": { - "_id": {"$concat": [ - {"$substr": [{"$year": "$timestamp"}, 0, 4]}, - "-", - {"$substr": [{"$month": "$timestamp"}, 0, 2]}, - "-", - {"$substr": [{"$dayOfMonth": "$timestamp"}, 0, 2]}, - ]}, - "count": {"$sum": 1} - }}, - {"$sort": {"_id": -1}} - ]) - for d in dateagg: - datelist.append({'count': d['count'], 'date': datetime.strptime(d['_id'], "%Y-%m-%d").date()}) - return list(datelist) - - -def get_poc_address(request): - addr_obj = list(request.db['pocConfiguration'].find({"_id": "pocIPAddress"})) - address = False - if len(addr_obj) > 0: - address = addr_obj[0]['pocIPAddress'] - return address - - -def set_password(request, username, password): - password_hash = poc_pwd_context.encrypt(password) - request.db['users'].update_one({'username': username}, {"$set":{"username": username, "password": password_hash}}, upsert=True) - - -def check_password(request, username, password): - users = list(request.db['users'].find({'username': username})) - if len(users) > 0: - this_user = users[0] - - # is it cleartext? - if password == this_user['password']: - set_password(request, username, password) - return check_password(request, username, password) - - return poc_pwd_context.verify(password, this_user['password']) diff --git a/pocwww/views.py b/pocwww/views.py index 906fc9d..2f402ca 100644 --- a/pocwww/views.py +++ b/pocwww/views.py @@ -1,9 +1,9 @@ from pyramid.view import view_config from pyramid.httpexceptions import HTTPFound from pyramid.security import remember, forget +from passlib.apps import custom_app_context as poc_pwd_context from datetime import datetime, timedelta from math import ceil -from .view_helpers import * @view_config(route_name='home', renderer='templates/dashboard.jinja2') @@ -38,67 +38,6 @@ def my_view(request): return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': latest_tag_values, 'card': latest_card} -@view_config(route_name="gaugeoff_all", renderer="templates/gaugeoff_all.jinja2") -@view_config(route_name="json_gaugeoff_all", renderer="prettyjson") -def gaugeoff_all(request): - gaugeoff_list = [] - dateagg = list(request.db['gaugeOff'].aggregate( - [ - { - '$project': { - 'yearMonthDay': {'$dateToString': {'format': "%Y-%m-%d", 'date': "$timestamp"}}, - 'tagname': 1, - 'dailyTotal': 1, - 'dailyAverage': 1, - 'maxDailyValue': 1, - 'minDailyValue': 1, - 'currentValue': 1 - } - }, - { - '$group': { - '_id': "$yearMonthDay", - 'tags': {'$push': {'name': "$tagname"}}, - 'totals': {'$push': {'total': "$dailyTotal"}}, - 'averages': {'$push': {'average': "$dailyAverage"}}, - 'max': {'$push': {'max': "$maxDailyValue"}}, - 'min': {'$push': {'min': "$minDailyValue"}}, - 'last': {'$push': {'last': "$currentValue"}} - } - } - ])) - for d in dateagg: - newGO = {'date': datetime.strptime(d["_id"], '%Y-%m-%d'), 'tags': {}} - for i in range(0, len(d['tags'])): - newTagObj = { - "max": d['max'][i]['max'], - "min": d['min'][i]['min'], - "last": d['last'][i]['last'], - "total": d['totals'][i]['total'], - "average": d['averages'][i]['average'], - } - newGO['tags'][d['tags'][i]['name']] = newTagObj - gaugeoff_list.append(newGO) - return {'navgroup': 'gaugeoff', 'data': gaugeoff_list} - - -@view_config(route_name="runstatus", renderer="templates/runstatus.jinja2") -@view_config(route_name="json_runstatus", renderer="prettyjson") -@view_config(route_name="json_runstatus_page", renderer="prettyjson") -def run_status(request): - page_num = 1 - try: - page_num = int(request.matchdict['page_num']) - except KeyError: - pass - - num_per_page = 100 - num_cards = request.db['runStatus'].count() - pages = ceil(num_cards / num_per_page) - runStatuses = list(request.db['runStatus'].find().sort("timestamp", -1).skip(num_per_page * (page_num - 1)).limit(num_per_page)) - return {'navgroup': 'runstatus', 'data': runStatuses, 'pagination': Pagination(page_num, num_per_page, num_cards)} - - @view_config(route_name="config", renderer="templates/config.jinja2", permission="edit") @view_config(route_name="json_config", renderer="prettyjson", permission="edit") def well_config(request): @@ -131,6 +70,73 @@ def register(request): return {"navgroup": "user"} -@view_config(route_name='setpoints', renderer='templates/setpoints.jinja2', permission='edit') -def setpoints(request): - return {"navgroup": "setpoints"} +def set_password(request, username, password): + password_hash = poc_pwd_context.encrypt(password) + request.db['users'].update_one({'username': username}, {"$set":{"username": username, "password": password_hash}}, upsert=True) + + +def check_password(request, username, password): + users = list(request.db['users'].find({'username': username})) + if len(users) > 0: + this_user = users[0] + + # is it cleartext? + if password == this_user['password']: + set_password(request, username, password) + return check_password(request, username, password) + + return poc_pwd_context.verify(password, this_user['password']) + +@view_config(route_name="json_users", renderer="prettyjson", request_method='POST', permission="edit") +def json_newuser(request): + jsb = request.json_body + if request.db['users'].count({"username": jsb['username']}) > 0: + fail_reason = "There is already a user with this username" + return {"status": 'fail', "info": fail_reason} + + elif len(jsb['username']) < 5: + fail_reason = "The username must be at least 5 characters" + return {"status": 'fail', "info": fail_reason} + + elif len(jsb['password']) < 5: + fail_reason = "The password must be at least 5 characters" + return {"status": 'fail', "info": fail_reason} + + else: + set_return = set_password(request, jsb['username'], jsb['password']) + return {'status': "OK"} + + +@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='GET') +def json_getuser(request): + user_list = [] + users = list(request.db['users'].find()) + for user in users: + user_list.append(user['username']) + return {'users': user_list} + + +@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='DELETE') +def json_deleteuser(request): + request.db['users'].remove({'username': request.json_body['username']}) + user_list = [] + users = list(request.db['users'].find()) + for user in users: + user_list.append(user['username']) + return {'users': user_list} + + +@view_config(route_name="json_users", renderer="prettyjson", request_method='PUT', permission="edit") +def json_updateuser(request): + jsb = request.json_body + if len(jsb['username']) < 5: + fail_reason = "The username must be at least 5 characters" + return {"status": 'fail', "info": fail_reason} + + elif len(jsb['password']) < 5: + fail_reason = "The password must be at least 5 characters" + return {"status": 'fail', "info": fail_reason} + + else: + set_return = set_password(request, jsb['username'], jsb['password']) + return {'status': "OK"} diff --git a/pocwww/well_tests.py b/pocwww/well_tests.py index e9e47c8..ab1f328 100644 --- a/pocwww/well_tests.py +++ b/pocwww/well_tests.py @@ -1,5 +1,4 @@ from pyramid.view import view_config -from .view_helpers import * @view_config(route_name="welltests_all", renderer="templates/welltests.jinja2") From e4ddc27f3f6e5a41e73c110d86fe98f467c86683 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 21 Apr 2017 17:50:59 -0500 Subject: [PATCH 6/6] More splitting files out --- pocwww/__init__.py | 53 ++++++------ pocwww/admin.py | 7 ++ pocwww/cards.py | 15 ++-- pocwww/config.py | 7 ++ pocwww/fluid_shots.py | 2 +- pocwww/gauge_off.py | 2 +- pocwww/home.py | 33 ++++++++ pocwww/poc_interface.py | 16 ++-- pocwww/run_status.py | 6 +- pocwww/security.py | 18 +++++ pocwww/templates/layout.jinja2 | 4 +- pocwww/users.py | 77 ++++++++++++++++++ pocwww/views.py | 142 --------------------------------- pocwww/well_tests.py | 2 +- 14 files changed, 194 insertions(+), 190 deletions(-) create mode 100644 pocwww/admin.py create mode 100644 pocwww/config.py create mode 100644 pocwww/home.py create mode 100644 pocwww/users.py delete mode 100644 pocwww/views.py diff --git a/pocwww/__init__.py b/pocwww/__init__.py index 30eb4bb..b64b882 100644 --- a/pocwww/__init__.py +++ b/pocwww/__init__.py @@ -125,19 +125,18 @@ def main(global_config, **settings): # SHARED ROUTES config.add_route('home', '/') - config.add_route('json_snapshot', '/json') - config.add_route("json_users", "/json/users", factory='pocwww.security.UserLoginFactory') + config.add_route('home_json', '/json') # Cards config.add_route('cards_page', '/cards/{cards_date}/{page_num}') - config.add_route('json_cards_page', '/json/cards/{cards_date}/{page_num}') + config.add_route('cards_page_json', '/json/cards/{cards_date}/{page_num}') config.add_route('cards_date', '/cards/{cards_date}') - config.add_route('json_cards_date', '/json/cards/{cards_date}') + config.add_route('cards_date_json', '/json/cards/{cards_date}') config.add_route('cards', '/cards') - config.add_route('json_cards', '/json/cards') - config.add_route('card_single', "/card/view/{stroke_number}") - config.add_route('json_card_single', "/json/card/view/{stroke_number}") - config.add_route('json_lastcard', "/json/lastcard") + config.add_route('cards_json', '/json/cards') + config.add_route('cards_singlecard', "/card/view/{stroke_number}") + config.add_route('cards_singlecard_json', "/json/card/view/{stroke_number}") + config.add_route('cards_lastcard_json', "/json/lastcard") # Measurements config.add_route('measurements_all', "/values") @@ -152,41 +151,43 @@ def main(global_config, **settings): # Gauge Off config.add_route('gaugeoff_all', '/gaugeoff') - config.add_route('json_gaugeoff_all', '/json/gaugeoff') + config.add_route('gaugeoff_all_json', '/json/gaugeoff') # Fluid Shots config.add_route('fluidshots_all', '/fluidshots') - config.add_route('json_fluidshots_all', '/json/fluidshots') + config.add_route('fluidshots_all_json', '/json/fluidshots') # Well Tests config.add_route('welltests_all', '/welltests') - config.add_route('json_welltests_all', '/json/welltests') + config.add_route('welltests_all_json', '/json/welltests') # Run Status config.add_route('runstatus', '/runstatus') - config.add_route('json_runstatus_page', '/json/runstatus/{page_num}') - config.add_route('json_runstatus', '/json/runstatus') - config.add_route('json_runstatusnow', "/json/runstatusnow") + config.add_route('runstatus_page_json', '/json/runstatus/{page_num}') + config.add_route('runstatus_json', '/json/runstatus') + config.add_route('runstatus_now_json', "/json/runstatusnow") # Configuration - config.add_route('json_config', '/json/config', factory='pocwww.security.UserLoginFactory') + config.add_route('config_json', '/json/config', factory='pocwww.security.UserLoginFactory') config.add_route('config', '/config', factory='pocwww.security.UserLoginFactory') - # Setpoints - config.add_route('json_setpoints', '/json/setpoints', factory='pocwww.security.UserLoginFactory') - config.add_route('json_mode', '/json/mode', factory='pocwww.security.UserLoginFactory') - config.add_route('setpoints', '/setpoints', factory='pocwww.security.UserLoginFactory') - # Administration config.add_route('admin', '/admin', factory='pocwww.security.UserLoginFactory') - config.add_route('auth', '/sign/{action}') - config.add_route('register', '/register', factory='pocwww.security.UserLoginFactory') + + # Users + config.add_route('users_auth', '/sign/{action}') + config.add_route('users_register', '/register', factory='pocwww.security.UserLoginFactory') + config.add_route("users_json", "/json/users", factory='pocwww.security.UserLoginFactory') + # POC Interface - config.add_route("json_updateconfig", "/json/updateconfig", factory='pocwww.security.UserLoginFactory') - config.add_route("json_shake", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') # Shake command is separate for allowing all access - config.add_route("json_cmd", '/json/cmd/{action}', factory='pocwww.security.UserLoginFactory') - config.add_route("json_update_poc_address", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory') + config.add_route("poc_updateconfig_json", "/json/updateconfig", factory='pocwww.security.UserLoginFactory') + config.add_route("poc_shake_json", '/json/cmd/shake', factory='pocwww.security.UserLoginFactory') # Shake command is separate for allowing all access + config.add_route("poc_cmd_json", '/json/cmd/{action}', factory='pocwww.security.UserLoginFactory') + config.add_route("poc_updatepocaddress_json", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory') + config.add_route('poc_setpoints_json', '/json/setpoints', factory='pocwww.security.UserLoginFactory') + config.add_route('poc_mode_json', '/json/mode', factory='pocwww.security.UserLoginFactory') + config.add_route('poc_setpoints', '/setpoints', factory='pocwww.security.UserLoginFactory') diff --git a/pocwww/admin.py b/pocwww/admin.py new file mode 100644 index 0000000..5d0a76d --- /dev/null +++ b/pocwww/admin.py @@ -0,0 +1,7 @@ +from pyramid.view import view_config + + +@view_config(route_name="admin", renderer="templates/admin.jinja2", permission="edit") +def admin_view(request): + address = get_poc_address(request) or 'localhost' + return {'navgroup': 'admin', 'pocIPAddress': address} diff --git a/pocwww/cards.py b/pocwww/cards.py index 183c202..e488917 100644 --- a/pocwww/cards.py +++ b/pocwww/cards.py @@ -1,4 +1,7 @@ from pyramid.view import view_config +from datetime import datetime +from datetime import timedelta +from math import ceil from .pagination import Pagination def get_all_dates_with_cards(request): @@ -20,21 +23,21 @@ def get_all_dates_with_cards(request): datelist.append({'count': d['count'], 'date': datetime.strptime(d['_id'], "%Y-%m-%d").date()}) return list(datelist) -@view_config(route_name="json_lastcard", renderer="prettyjson") +@view_config(route_name="cards_lastcard_json", renderer="prettyjson") def json_lastcard(request): return get_latest_card(request) @view_config(route_name='cards', renderer='templates/datelist.jinja2') -@view_config(route_name='json_cards', renderer='prettyjson') +@view_config(route_name='cards_json', renderer='prettyjson') def cards(request): return {'datelist': get_all_dates_with_cards(request), 'navgroup': 'cards'} @view_config(route_name='cards_page', renderer='templates/cardlist.jinja2') @view_config(route_name='cards_date', renderer='templates/cardlist.jinja2') -@view_config(route_name='json_cards_date', renderer='prettyjson') -@view_config(route_name='json_cards_page', renderer='prettyjson') +@view_config(route_name='cards_date_json', renderer='prettyjson') +@view_config(route_name='cards_page_json', renderer='prettyjson') def cards_page(request): page_num = 1 try: @@ -64,8 +67,8 @@ def cards_page(request): } -@view_config(route_name='card_single', renderer='templates/cardsingle.jinja2') -@view_config(route_name='json_card_single', renderer='prettyjson') +@view_config(route_name='cards_singlecard', renderer='templates/cardsingle.jinja2') +@view_config(route_name='cards_singlecard_json', renderer='prettyjson') def card_single(request): card = {} try: diff --git a/pocwww/config.py b/pocwww/config.py new file mode 100644 index 0000000..ff07722 --- /dev/null +++ b/pocwww/config.py @@ -0,0 +1,7 @@ +from pyramid.view import view_config + +@view_config(route_name="config", renderer="templates/config.jinja2", permission="edit") +@view_config(route_name="config_json", renderer="prettyjson", permission="edit") +def well_config(request): + current_configuration = list(request.db['wellConfiguration'].find().sort("timestamp", -1).limit(1))[0] + return {'navgroup': 'config', 'config': current_configuration} diff --git a/pocwww/fluid_shots.py b/pocwww/fluid_shots.py index 3698990..704dcd7 100644 --- a/pocwww/fluid_shots.py +++ b/pocwww/fluid_shots.py @@ -2,7 +2,7 @@ from pyramid.view import view_config @view_config(route_name="fluidshots_all", renderer="templates/fluidshots.jinja2") -@view_config(route_name="json_fluidshots_all", renderer="prettyjson") +@view_config(route_name="fluidshots_all_json", renderer="prettyjson") def fluidshots_all(request): fluidshots = list(request.db['fluidShots'].find()) return {'navgroup': 'fluidshots', 'data': fluidshots} diff --git a/pocwww/gauge_off.py b/pocwww/gauge_off.py index a5a19b1..b5d1633 100644 --- a/pocwww/gauge_off.py +++ b/pocwww/gauge_off.py @@ -1,7 +1,7 @@ from pyramid.view import view_config @view_config(route_name="gaugeoff_all", renderer="templates/gaugeoff_all.jinja2") -@view_config(route_name="json_gaugeoff_all", renderer="prettyjson") +@view_config(route_name="gaugeoff_all_json", renderer="prettyjson") def gaugeoff_all(request): gaugeoff_list = [] dateagg = list(request.db['gaugeOff'].aggregate( diff --git a/pocwww/home.py b/pocwww/home.py new file mode 100644 index 0000000..13affe7 --- /dev/null +++ b/pocwww/home.py @@ -0,0 +1,33 @@ +from pyramid.view import view_config + + +@view_config(route_name='home', renderer='templates/dashboard.jinja2') +@view_config(route_name="home_json", renderer="prettyjson") +def my_view(request): + latest_tag_values = [] + latesttag_agg = request.db['measurements'].aggregate([ + {'$sort': {'dateStored': 1}}, + { + '$group': { + '_id': '$tagname', + 'currentValue': {'$last': '$currentValue'}, + 'units': {'$last': '$units'}, + 'maxValue': {'$last': '$maxValue'}, + 'minValue': {'$last': '$minValue'}, + 'totalValue': {'$last': '$totalValue'}, + 'averageValue': {'$last': '$averageValue'}, + 'useTotal': {'$last': '$useTotal'}, + 'useAverage': {'$last': '$useAverage'} + } + } + ]) + for t in latesttag_agg: + latest_tag_values.append(t) + + latest_card = [] + try: + latest_card = list(request.db['cards'].find().sort("timestamp", -1).limit(1))[0] + except IndexError: + latest_card = [] + + return {'project': 'POC Web Interface', 'navgroup': 'dashboard', 'tag_values': latest_tag_values, 'card': latest_card} diff --git a/pocwww/poc_interface.py b/pocwww/poc_interface.py index 2f3da7c..d645870 100644 --- a/pocwww/poc_interface.py +++ b/pocwww/poc_interface.py @@ -10,7 +10,7 @@ def get_poc_address(request): return address -@view_config(route_name="json_updateconfig", renderer="prettyjson", request_method='POST', permission="edit") +@view_config(route_name="poc_updateconfig_json", renderer="prettyjson", request_method='POST', permission="edit") def json_updateconfig(request): conv_to_float = [ 'deltaT', @@ -54,7 +54,7 @@ def json_updateconfig(request): return {'new_config': request.json_body, 'stored_result': result, 'updated': pocCmdSts} -@view_config(route_name="json_cmd", renderer="prettyjson", permission="edit") +@view_config(route_name="poc_cmd_json", renderer="prettyjson", permission="edit") def json_cmd(request): print("got here") action = request.matchdict['action'] @@ -69,7 +69,7 @@ def json_cmd(request): return r.text if r.status_code == 200 else {"status": "failure sending command"} -@view_config(route_name="json_shake", renderer="prettyjson", permission="view") +@view_config(route_name="poc_shake_json", renderer="prettyjson", permission="view") def json_shake(request): address = get_poc_address(request) or 'localhost' url = "http://{}:8000/shake".format(address) @@ -78,7 +78,7 @@ def json_shake(request): return r.text if r.status_code == 200 else {"status": "failure sending command"} -@view_config(route_name="json_update_poc_address", renderer="prettyjson", request_method='POST', permission="edit") +@view_config(route_name="poc_updatepocaddress_json", renderer="prettyjson", request_method='POST', permission="edit") def json_update_poc_address(request): try: new_addr = request.json_body['pocIPAddress'] @@ -88,17 +88,17 @@ def json_update_poc_address(request): return {"status": "failure"} -@view_config(route_name='setpoints', renderer='templates/setpoints.jinja2', permission='edit') +@view_config(route_name='poc_setpoints', renderer='templates/setpoints.jinja2', permission='edit') def setpoints(request): return {"navgroup": "setpoints"} -@view_config(route_name="json_setpoints", renderer="prettyjson", request_method='GET', permission='edit') +@view_config(route_name="poc_setpoints_json", renderer="prettyjson", request_method='GET', permission='edit') def json_setpoints(request): return {'setpoints': list(request.db['setpoints'].find())} -@view_config(route_name="json_setpoints", renderer="prettyjson", request_method='POST', permission='edit') +@view_config(route_name="poc_setpoints_json", renderer="prettyjson", request_method='POST', permission='edit') def json_setpoints_post(request): jsb = request.json_body try: @@ -120,7 +120,7 @@ def json_setpoints_post(request): runModes = {0: 'poc', 1: 'manual', 2: 'timer'} -@view_config(route_name="json_mode", renderer="prettyjson", request_method='POST', permission='edit') +@view_config(route_name="poc_mode_json", renderer="prettyjson", request_method='POST', permission='edit') def json_mode_post(request): jsb = request.json_body try: diff --git a/pocwww/run_status.py b/pocwww/run_status.py index cd35e6e..f6d0fb5 100644 --- a/pocwww/run_status.py +++ b/pocwww/run_status.py @@ -3,8 +3,8 @@ from math import ceil from .pagination import Pagination @view_config(route_name="runstatus", renderer="templates/runstatus.jinja2") -@view_config(route_name="json_runstatus", renderer="prettyjson") -@view_config(route_name="json_runstatus_page", renderer="prettyjson") +@view_config(route_name="runstatus_json", renderer="prettyjson") +@view_config(route_name="runstatus_page_json", renderer="prettyjson") def run_status(request): page_num = 1 try: @@ -19,7 +19,7 @@ def run_status(request): return {'navgroup': 'runstatus', 'data': runStatuses, 'pagination': Pagination(page_num, num_per_page, num_cards)} -@view_config(route_name="json_runstatusnow", renderer="prettyjson") +@view_config(route_name="runstatus_now_json", renderer="prettyjson") def json_runstatusnow(request): status = False try: diff --git a/pocwww/security.py b/pocwww/security.py index 3c2e501..c3d3434 100644 --- a/pocwww/security.py +++ b/pocwww/security.py @@ -1,4 +1,5 @@ from pyramid.security import Allow, Everyone, Authenticated +from passlib.apps import custom_app_context as poc_pwd_context class UserLoginFactory(object): @@ -8,3 +9,20 @@ class UserLoginFactory(object): def __init__(self, request): pass + +def set_password(request, username, password): + password_hash = poc_pwd_context.encrypt(password) + request.db['users'].update_one({'username': username}, {"$set":{"username": username, "password": password_hash}}, upsert=True) + + +def check_password(request, username, password): + users = list(request.db['users'].find({'username': username})) + if len(users) > 0: + this_user = users[0] + + # is it cleartext? + if password == this_user['password']: + set_password(request, username, password) + return check_password(request, username, password) + + return poc_pwd_context.verify(password, this_user['password']) diff --git a/pocwww/templates/layout.jinja2 b/pocwww/templates/layout.jinja2 index c76c11b..a2d952d 100644 --- a/pocwww/templates/layout.jinja2 +++ b/pocwww/templates/layout.jinja2 @@ -67,9 +67,9 @@
  • Setpoints
  • Well Setup
  • {{request.authenticated_userid}}
  • -
  • +
  • {% else %} -