Changeset - 00d1f8ab3675
[Not reviewed]
default
0 1 4
Dennis Fink - 10 years ago 2015-07-04 16:43:26
dennis.fink@c3l.lu
Added more development files
5 files changed with 152 insertions and 12 deletions:
0 comments (0 inline, 0 general)
dev-requirements.txt
Show inline comments
 
new file 100644
 
alabaster==0.7.4
 
Babel==1.3
 
docutils==0.12
 
Jinja2==2.7.3
 
MarkupSafe==0.23
 
pip-tools==0.3.6
 
Pygments==2.0.2
 
pytz==2015.4
 
six==1.9.0
 
snowballstemmer==1.2.0
 
sphinx-rtd-theme==0.1.8
 
Sphinx==1.3.1
 
wheel==0.24.0
requirements.txt
Show inline comments
 
new file 100644
run.py
Show inline comments
 
new file 100644
 
from spaceapi import app
 

	
 
app.run(debug=True)
setup.py
Show inline comments
 
new file 100644
 
from pprint import pprint
 

	
 
from setuptools import setup, find_packages
 

	
 
packages = find_packages()
 
packages.append('spaceapi.templates')
 
packages.append('spaceapi.static')
 

	
 
setup(
 
    name='c3l_spaceapi',
 
    version='0.0.1',
 
    url=None,
 
    license='GPLv3+',
 
    author='Dennis Fink',
 
    author_email='dennis.fink@c3l.lu',
 
    description='spaceapi endpoint for c3l.lu',
 
    packages=packages,
 
    package_data={
 
        'spaceapi.templates': ['*'],
 
        'spaceapi.static': ['*']
 
    },
 
    install_requires=['Flask', 'Flask-HTTPAuth']
 
)
spaceapi/__init__.py
Show inline comments
 
@@ -5,22 +5,48 @@ import calendar
 
import base64
 
import copy
 

	
 
from datetime import datetime
 
from time import time
 
from ast import literal_eval
 

	
 
from flask import Flask, jsonify, request, render_template
 
from flask.ext.httpauth import HTTPDigestAuth
 

	
 
import jsonschema
 

	
 
from pkg_resources import resource_filename
 

	
 
ALLOWED_STATE_KEYS = {
 
    'open': bool,
 
    'lastchange': int,
 
    'trigger_person': str,
 
    'message': str
 
}
 

	
 
ALLOWED_SENSORS_KEYS = json.load(
 
    open(resource_filename('spaceapi', 'schema/sensors.json'),
 
         encoding='utf-8')
 
)
 

	
 
config_file = os.path.abspath('config.json')
 
default_json_file = os.path.abspath('default.json')
 
last_state_file = os.path.abspath('laststate.json')
 

	
 
default_json = {}
 
active_json = {}
 

	
 

	
 
def reload_json():
 
    global default_json
 
    global active_json
 

	
 
default_json = json.load(open(default_json_file, encoding='utf-8'))
 

	
 
if os.path.exists(last_state_file):
 
    with open(last_state_file, encoding='utf-8') as f:
 
        active_json = json.load(f)
 

	
 
    if os.path.getmtime(last_state_file) < os.path.getmtime(default_json_file):
 
        if os.path.getmtime(last_state_file) \
 
           < os.path.getmtime(default_json_file):
 
        backup = copy.deepcopy(active_json)
 
        active_json.update(default_json)
 
        active_json['state']['open'] = backup['state']['open']
 
@@ -28,6 +54,8 @@ if os.path.exists(last_state_file):
 
else:
 
    active_json = copy.deepcopy(default_json)
 

	
 
reload_json()
 

	
 
app = Flask(__name__)
 
auth = HTTPDigestAuth()
 

	
 
@@ -79,6 +107,7 @@ def save_last_state():
 

	
 
@app.route('/')
 
def index():
 

	
 
    if request_wants_json():
 
        return jsonify(active_json)
 
    return render_template('index.html', status=active_json)
 
@@ -89,21 +118,93 @@ def status_json():
 
    return jsonify(active_json)
 

	
 

	
 
@app.route('/set_state/<state>', methods=('PUT',))
 
@app.route('/set/state/<key>/<value>', methods=['POST'])
 
@auth.login_required
 
def set_state(state):
 
def set_state(key, value):
 

	
 
    value = literal_eval(value)
 

	
 
    if state == 'open':
 
        active_json['state']['open'] = True
 
    elif state == 'close':
 
        active_json['state']['open'] = False
 
    if key in ALLOWED_STATE_KEYS and isinstance(value,
 
                                                ALLOWED_STATE_KEYS[key]):
 
        active_json['state'][key] = value
 

	
 
        if key == 'open':
 
            active_json['state']['lastchange'] = int(time.time())
 
    else:
 
        return 400
 

	
 
    active_json['state']['lastchange'] = calendar.timegm(
 
        datetime.now().timetuple()
 
    )
 

	
 
    save_last_state()
 

	
 
    return jsonify(active_json)
 

	
 

	
 
def fuzzy_list_find(lst, key, value):
 

	
 
    for i, dic in enumerate(lst):
 
        if dic[key] == value:
 
            return i
 

	
 
    raise ValueError
 

	
 

	
 
@app.route('/set/sensors/<key>', methods=['POST'])
 
@auth.login_required
 
def set_sensors(key):
 

	
 
    if key in ALLOWED_SENSORS_KEYS and key in active_json['sensors']:
 
        data = request.data
 
        try:
 
            data = json.loads(data)
 
            try:
 
                jsonschema.validate(data, ALLOWED_SENSORS_KEYS[key])
 

	
 
                if key != 'radiation':
 
                    for subkey in ('name', 'location'):
 
                        if subkey in data:
 
                            index = fuzzy_list_find(
 
                                active_json['sensors'][key],
 
                                subkey, data[subkey]
 
                            )
 
                            active_json['sensors'][key][index].update(data)
 
                        else:
 
                            return 400
 
                else:
 
                    for first_subkey in ('alpha', 'beta',
 
                                         'gamma' 'beta_gamma'):
 
                        for second_subkey in ('name', 'location'):
 
                            if second_subkey in data[first_subkey]:
 
                                index = fuzzy_list_find(
 
                                    active_json['sensors'][key][first_subkey],
 
                                    second_subkey,
 
                                    data[first_subkey][second_subkey])
 
                                active_json['sensors'][
 
                                    key
 
                                ][first_subkey][index].update(data)
 
                            else:
 
                                return 400
 

	
 
            except jsonschema.ValidationError:
 
                return 400
 
        except:
 
            return 400
 
    else:
 
        return 400
 

	
 
    save_last_state()
 

	
 
    return jsonify(active_json)
 

	
 

	
 
@app.route('/reload')
 
@auth.login_required
 
def reload():
 
    reload_json()
 
    return 200
 

	
 

	
 
@app.after_request
 
def add_headers(response):
 
    response.headers.setdefault('Access-Control-Allow-Origin', '*')
 
    response.headers.setdefault('Cache-Control', 'no-cache')
 

	
 
    return response
0 comments (0 inline, 0 general)