Changeset - 1438a15c1120
[Not reviewed]
default
0 3 0
Dennis Fink - 8 years ago 2017-10-08 17:06:30
dennis.fink@c3l.lu
Add spaceapi v14 support
3 files changed with 50 insertions and 8 deletions:
0 comments (0 inline, 0 general)
spaceapi/__init__.py
Show inline comments
 
@@ -90,16 +90,17 @@ def create_app():
 

	
 
        return response
 

	
 
    from .views import root_views
 
    app.register_blueprint(root_views)
 

	
 
    from .state import state_views
 
    app.register_blueprint(state_views, url_prefix='/state')
 

	
 
    from .sensors import sensors_views
 
    app.register_blueprint(sensors_views, url_prefix='/sensors')
 

	
 
    from .utils import ActiveStatus
 
    from .utils import ActiveStatus, ActiveStatusv14
 
    ActiveStatus().reload()
 
    ActiveStatusv14().reload()
 

	
 
    return app
spaceapi/utils.py
Show inline comments
 
@@ -3,29 +3,38 @@ import os.path
 
from time import time
 
import random
 
from functools import wraps
 

	
 
from flask import request, current_app
 

	
 
import tweepy
 

	
 

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

	
 
default_json_file_v14 = os.path.abspath('default_v14.json')
 
last_state_file_v14 = os.path.abspath('laststate_v14.json')
 

	
 
if not os.path.exists(default_json_file):
 
    raise RuntimeError('default.json does not exists!')
 
elif not os.path.isfile(default_json_file):
 
    raise RuntimeError('default.json is not a file!')
 

	
 
if not os.path.exists(default_json_file_v14):
 
    raise RuntimeError('default_v14.json does not exists!')
 
elif not os.path.isfile(default_json_file):
 
    raise RuntimeError('default_v14.json is not a file!')
 

	
 

	
 
possible_open_tweets = (
 
    'The space is now open!',
 
    'The space is open! Come in and hack something!',
 
    'Yes, we\'re open! Come in and create something!',
 
    'Come by and hack something! We\'ve just opened!',
 
    'The ChaosStuff is now open for everyone!',
 
)
 

	
 
possible_closed_tweets = (
 
    'The space is now closed!',
 
    'We\'re closed now! See you soon.',
 
    'Sorry, we are closed now!',
 
@@ -58,39 +67,43 @@ class Singleton:
 

	
 
        if not hasattr(cls, '_instance_dict'):
 
            cls._instance_dict = {}
 

	
 
        if key not in cls._instance_dict:
 
            cls._instance_dict[key] = super().__new__(cls, *args, **kwargs)
 

	
 
        return cls._instance_dict[key]
 

	
 

	
 
class ActiveStatus(Singleton, dict):
 

	
 
    def __init__(self):
 
        self.default_json_file = default_json_file
 
        self.last_state_file = last_state_file
 

	
 
    def reload(self):
 

	
 
        with open(default_json_file, encoding='utf-8') as f:
 
        with open(self.default_json_file, encoding='utf-8') as f:
 
            self.update(json.load(f))
 

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

	
 
            self['state'] = last_state_json['state']
 
            self['sensors'].update(last_state_json['sensors'])
 

	
 
    def save_last_state(self):
 

	
 
        with open(last_state_file, mode='w', encoding='utf-8') as f:
 
        with open(self.last_state_file, mode='w', encoding='utf-8') as f:
 
            last_state = {}
 
            last_state['state'] = self['state']
 
            last_state['sensors'] = self['sensors']
 
            json.dump(last_state, f, sort_keys=True)
 

	
 
    def add_user_present(self, username):
 
        if self['state']['open']:
 
            if 'people_now_present' not in self['sensors']:
 
                self['sensors']['people_now_present'] = [{'value': 0}]
 

	
 
            people_now_present = self['sensors']['people_now_present'][0]
 

	
 
@@ -158,24 +171,31 @@ class ActiveStatus(Singleton, dict):
 

	
 
            if trigger_person is None:
 
                del self['state']['trigger_person']
 
            else:
 
                self['state']['trigger_person'] = trigger_person
 

	
 
            self['state']['lastchange'] = int(time())
 

	
 
        if message is not None:
 
            self['state']['message'] = message
 

	
 

	
 
class ActiveStatusv14(ActiveStatus):
 

	
 
    def __init__(self):
 
        self.default_json_file = default_json_file_v14
 
        self.last_state_file = last_state_file_v14
 

	
 

	
 
def request_wants_json():
 
    best = request.accept_mimetypes.best_match(
 
        ['application/json', 'text/html']
 
    )
 
    return best == 'application/json' and \
 
        request.accept_mimetypes[best] > \
 
        request.accept_mimetypes['text/html']
 

	
 

	
 
def fuzzy_list_find(lst, key, value):
 

	
 
    for i, dic in enumerate(lst):
spaceapi/views.py
Show inline comments
 
from flask import Blueprint, jsonify, render_template, abort, request, redirect, url_for, current_app
 

	
 
from .utils import request_wants_json, ActiveStatus
 
from .utils import request_wants_json, ActiveStatus, ActiveStatusv14
 
from .auth import httpauth
 

	
 
root_views = Blueprint('root', __name__)
 

	
 

	
 
@root_views.route('/')
 
def index():
 
    if request_wants_json():
 
        return jsonify(ActiveStatus())
 
    return render_template('index.html', status=ActiveStatus())
 

	
 

	
 
@root_views.route('/status.json')
 
def status_json():
 
    return jsonify(ActiveStatus())
 

	
 

	
 
@root_views.route('/v14/status.json')
 
def v14_json():
 
    return jsonify(ActiveStatusv14())
 

	
 

	
 
@root_views.route('/reload')
 
@httpauth.login_required
 
def reload():
 
    active = ActiveStatus()
 
    active.reload()
 
    return jsonify(active)
 

	
 

	
 
@root_views.route('/v14/reload')
 
@httpauth.login_required
 
def v14_reload():
 
    active = ActiveStatusv14()
 
    active.reload()
 
    return jsonify(active)
 

	
 

	
 
@root_views.route('/open', methods=('GET', 'POST'))
 
@httpauth.login_required
 
def open():
 
    if request.method == 'POST':
 
        active = ActiveStatus()
 
        activev14 = ActiveStatusv14()
 

	
 
        try:
 
            if httpauth.username() in current_app.config['STATE_TRIGGER_PERSON_ALLOWED']:
 
                trigger_person = httpauth.username()
 
            else:
 
                trigger_person = None
 
        except KeyError:
 
            trigger_person = None
 

	
 
        if 'close' in request.form:
 
            new_state = False
 
        elif 'open' in request.form:
 
            new_state = True
 

	
 
        active.set_new_state(value=new_state, trigger_person=trigger_person)
 
        activev14.set_new_state(value=new_state, trigger_person=trigger_person)
 
        active.save_last_state()
 
        activev14.save_last_state()
 
        return redirect(url_for('root.index'))
 

	
 
    return render_template('open.html')
 

	
 

	
 
@root_views.route('/present', methods=('GET', 'POST'))
 
@httpauth.login_required
 
def present():
 
    if request.method == 'POST':
 

	
 
        active = ActiveStatus()
 
        activev14 = ActiveStatusv14()
 

	
 
        if active['state']['open']:
 
            user = httpauth.username()
 
            if 'present' in request.form:
 
                active.add_user_present(httpauth.username())
 
                active.add_user_present(user)
 
                activev14.add_user_present(user)
 
            elif 'leave' in request.form:
 
                active.remove_user_present(httpauth.username())
 
                active.remove_user_present(user)
 
                activev14.remove_user_present(user)
 
            active.save_last_state()
 
            activev14.save_last_state()
 
        return redirect(url_for('root.index'))
 

	
 
    return render_template('present.html')
0 comments (0 inline, 0 general)