- Several UI Adjustments - still work in progress - New API Method to add custom JavaScript to CraftBeerPi - Global Action Buttons added - Register new Web Modules for complete custom UItags/3.1_alpha
| @@ -1,5 +1,7 @@ | |||||
| import time | import time | ||||
| from flask_classy import route | from flask_classy import route | ||||
| from flask_login import login_required | |||||
| from modules.core.db import DBModel | from modules.core.db import DBModel | ||||
| from modules.core.core import cbpi | from modules.core.core import cbpi | ||||
| from modules.core.baseview import BaseView | from modules.core.baseview import BaseView | ||||
| @@ -21,6 +23,7 @@ class ActorView(BaseView): | |||||
| def _post_put_callback(self, m): | def _post_put_callback(self, m): | ||||
| self.api.actor.init_one(m.id) | self.api.actor.init_one(m.id) | ||||
| @login_required | |||||
| @route("<int:id>/switch/on", methods=["POST"]) | @route("<int:id>/switch/on", methods=["POST"]) | ||||
| def on(self, id): | def on(self, id): | ||||
| """ | """ | ||||
| @@ -42,6 +45,7 @@ class ActorView(BaseView): | |||||
| self.api.actor.on(id) | self.api.actor.on(id) | ||||
| return ('', 204) | return ('', 204) | ||||
| @login_required | |||||
| @route("<int:id>/switch/off", methods=["POST"]) | @route("<int:id>/switch/off", methods=["POST"]) | ||||
| def off(self, id): | def off(self, id): | ||||
| """ | """ | ||||
| @@ -63,6 +67,7 @@ class ActorView(BaseView): | |||||
| self.api.actor.off(id) | self.api.actor.off(id) | ||||
| return ('', 204) | return ('', 204) | ||||
| @login_required | |||||
| @route("<int:id>/power/<int:power>", methods=["POST"]) | @route("<int:id>/power/<int:power>", methods=["POST"]) | ||||
| def power(self, id, power): | def power(self, id, power): | ||||
| """ | """ | ||||
| @@ -90,6 +95,7 @@ class ActorView(BaseView): | |||||
| self.api.actor.power(id, power) | self.api.actor.power(id, power) | ||||
| return ('', 204) | return ('', 204) | ||||
| @login_required | |||||
| @route("<int:id>/toggle", methods=["POST"]) | @route("<int:id>/toggle", methods=["POST"]) | ||||
| def toggle(self, id): | def toggle(self, id): | ||||
| """ | """ | ||||
| @@ -108,10 +114,7 @@ class ActorView(BaseView): | |||||
| 200: | 200: | ||||
| description: Actor toggled | description: Actor toggled | ||||
| """ | """ | ||||
| if self.api.cache.get("actors").get(id).state == 0: | |||||
| self.on(id) | |||||
| else: | |||||
| self.off(id) | |||||
| cbpi.actor.toggle(id) | |||||
| return ('', 204) | return ('', 204) | ||||
| def toggleTimeJob(self, id, t): | def toggleTimeJob(self, id, t): | ||||
| @@ -121,6 +124,7 @@ class ActorView(BaseView): | |||||
| self.api.cache.get("actors").get(int(id)).timer = None | self.api.cache.get("actors").get(int(id)).timer = None | ||||
| self.toggle(int(id)) | self.toggle(int(id)) | ||||
| @login_required | |||||
| @route("/<id>/toggle/<int:t>", methods=["POST"]) | @route("/<id>/toggle/<int:t>", methods=["POST"]) | ||||
| def toggleTime(self, id, t): | def toggleTime(self, id, t): | ||||
| """ | """ | ||||
| @@ -145,9 +149,11 @@ class ActorView(BaseView): | |||||
| 200: | 200: | ||||
| description: Actor toggled | description: Actor toggled | ||||
| """ | """ | ||||
| t = self.api._socketio.start_background_task(target=self.toggleTimeJob, id=id, t=t) | |||||
| self.api.actor.toggle_timeout(id, t) | |||||
| #t = self.api._socketio.start_background_task(target=self.toggleTimeJob, id=id, t=t) | |||||
| return ('', 204) | return ('', 204) | ||||
| @login_required | |||||
| @route('<int:id>/action/<method>', methods=["POST"]) | @route('<int:id>/action/<method>', methods=["POST"]) | ||||
| def action(self, id, method): | def action(self, id, method): | ||||
| """ | """ | ||||
| @@ -172,7 +178,8 @@ class ActorView(BaseView): | |||||
| 200: | 200: | ||||
| description: Actor Action called | description: Actor Action called | ||||
| """ | """ | ||||
| cbpi.cache.get("actors").get(id).instance.__getattribute__(method)() | |||||
| self.api.actor.action(id, method) | |||||
| return ('', 204) | return ('', 204) | ||||
| @@ -26,7 +26,6 @@ class Dummy(Actor): | |||||
| @cbpi.addon.kettle.controller() | @cbpi.addon.kettle.controller() | ||||
| class MyController(KettleController): | class MyController(KettleController): | ||||
| def run(self): | def run(self): | ||||
| while self.is_running(): | while self.is_running(): | ||||
| print "HALLO" | print "HALLO" | ||||
| @@ -1,4 +1,8 @@ | |||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
| import os | |||||
| from os.path import join | |||||
| from modules.core.basetypes import Actor, Sensor | from modules.core.basetypes import Actor, Sensor | ||||
| from modules.core.core import cbpi | from modules.core.core import cbpi | ||||
| from modules.core.proptypes import Property | from modules.core.proptypes import Property | ||||
| @@ -33,4 +37,11 @@ class Dummy(Sensor): | |||||
| @cbpi.addon.core.action(key="clear", label="Clear all Logs") | @cbpi.addon.core.action(key="clear", label="Clear all Logs") | ||||
| def woohoo(cbpi): | def woohoo(cbpi): | ||||
| print "COOL" | print "COOL" | ||||
| cbpi.notify(headline="HELLO WORLD",message="") | |||||
| dir = "./logs" | |||||
| test = os.listdir(dir) | |||||
| for item in test: | |||||
| if item.endswith(".log"): | |||||
| os.remove(join(dir, item)) | |||||
| cbpi.notify(headline="Logs Deleted",message="All Logs Cleared") | |||||
| @@ -7,6 +7,10 @@ from modules.core.proptypes import Property | |||||
| class Dummy(Step): | class Dummy(Step): | ||||
| @cbpi.addon.step.action("WOHOO") | |||||
| def myaction(self): | |||||
| print "HALLO" | |||||
| text = Property.Text(label="Text", configurable=True, description="WOHOOO") | text = Property.Text(label="Text", configurable=True, description="WOHOOO") | ||||
| def execute(self): | def execute(self): | ||||
| @@ -87,6 +87,9 @@ class StepAPI(BaseAPI): | |||||
| return func | return func | ||||
| return real_decorator | return real_decorator | ||||
| class ActorAPI(BaseAPI): | class ActorAPI(BaseAPI): | ||||
| key = "actor_types" | key = "actor_types" | ||||
| @@ -150,6 +153,8 @@ class CoreAPI(BaseAPI): | |||||
| self.cbpi.cache["init"] = [] | self.cbpi.cache["init"] = [] | ||||
| self.cbpi.cache["js"] = {} | self.cbpi.cache["js"] = {} | ||||
| self.cbpi.cache["background"] = [] | self.cbpi.cache["background"] = [] | ||||
| self.cbpi.cache["web_menu"] =[] | |||||
| def init(self): | def init(self): | ||||
| self.cbpi.cache["init"] = sorted(self.cbpi.cache["init"], key=lambda k: k['order']) | self.cbpi.cache["init"] = sorted(self.cbpi.cache["init"], key=lambda k: k['order']) | ||||
| @@ -173,6 +178,9 @@ class CoreAPI(BaseAPI): | |||||
| def add_js(self, name, file): | def add_js(self, name, file): | ||||
| self.cbpi.cache["js"][name] = file | self.cbpi.cache["js"][name] = file | ||||
| def add_menu_link(self, name, path): | |||||
| self.cbpi.cache["web_menu"].append(dict(name=name, path=path)) | |||||
| def initializer(self, order=0, **options): | def initializer(self, order=0, **options): | ||||
| def decorator(f): | def decorator(f): | ||||
| self.cbpi.cache.get("init").append({"function": f, "order": order}) | self.cbpi.cache.get("init").append({"function": f, "order": order}) | ||||
| @@ -246,4 +246,5 @@ class Step(Base): | |||||
| self.__dirty = True | self.__dirty = True | ||||
| super(Step, self).__setattr__(name, value) | super(Step, self).__setattr__(name, value) | ||||
| else: | else: | ||||
| super(Step, self).__setattr__(name, value) | |||||
| super(Step, self).__setattr__(name, value) | |||||
| @@ -1,5 +1,7 @@ | |||||
| from flask import request, json | from flask import request, json | ||||
| from flask_classy import route, FlaskView | from flask_classy import route, FlaskView | ||||
| from flask_login import login_required | |||||
| from modules.core.core import cbpi | from modules.core.core import cbpi | ||||
| @@ -9,6 +11,7 @@ class BaseView(FlaskView): | |||||
| cache_key = None | cache_key = None | ||||
| api = cbpi | api = cbpi | ||||
| @login_required | |||||
| @route('/<int:id>', methods=["GET"]) | @route('/<int:id>', methods=["GET"]) | ||||
| def getOne(self, id): | def getOne(self, id): | ||||
| if self.api.cache.get(self.cache_key) is not None: | if self.api.cache.get(self.cache_key) is not None: | ||||
| @@ -16,6 +19,7 @@ class BaseView(FlaskView): | |||||
| else: | else: | ||||
| return json.dumps(self.model.get_one(id)) | return json.dumps(self.model.get_one(id)) | ||||
| @login_required | |||||
| @route('/', methods=["GET"]) | @route('/', methods=["GET"]) | ||||
| def getAll(self): | def getAll(self): | ||||
| if self.api.cache.get(self.cache_key) is not None: | if self.api.cache.get(self.cache_key) is not None: | ||||
| @@ -30,6 +34,7 @@ class BaseView(FlaskView): | |||||
| def _post_post_callback(self, m): | def _post_post_callback(self, m): | ||||
| pass | pass | ||||
| @login_required | |||||
| @route('/', methods=["POST"]) | @route('/', methods=["POST"]) | ||||
| def post(self): | def post(self): | ||||
| @@ -50,7 +55,7 @@ class BaseView(FlaskView): | |||||
| def _post_put_callback(self, m): | def _post_put_callback(self, m): | ||||
| pass | pass | ||||
| @login_required | |||||
| @route('/<int:id>', methods=["PUT"]) | @route('/<int:id>', methods=["PUT"]) | ||||
| def put(self, id): | def put(self, id): | ||||
| data = request.json | data = request.json | ||||
| @@ -78,6 +83,7 @@ class BaseView(FlaskView): | |||||
| def _post_delete_callback(self, id): | def _post_delete_callback(self, id): | ||||
| pass | pass | ||||
| @login_required | |||||
| @route('/<int:id>', methods=["DELETE"]) | @route('/<int:id>', methods=["DELETE"]) | ||||
| def delete(self, id): | def delete(self, id): | ||||
| if self.api.cache.get(self.cache_key) is not None: | if self.api.cache.get(self.cache_key) is not None: | ||||
| @@ -7,6 +7,7 @@ from datetime import datetime | |||||
| from functools import wraps, update_wrapper | from functools import wraps, update_wrapper | ||||
| from importlib import import_module | from importlib import import_module | ||||
| from time import localtime, strftime | from time import localtime, strftime | ||||
| import time | |||||
| from flask import Flask, redirect, json, g, make_response | from flask import Flask, redirect, json, g, make_response | ||||
| from flask_socketio import SocketIO | from flask_socketio import SocketIO | ||||
| @@ -17,6 +18,7 @@ from modules.core.basetypes import Sensor, Actor | |||||
| from modules.database.dbmodel import Kettle | from modules.database.dbmodel import Kettle | ||||
| class ComplexEncoder(json.JSONEncoder): | class ComplexEncoder(json.JSONEncoder): | ||||
| def default(self, obj): | def default(self, obj): | ||||
| try: | try: | ||||
| @@ -109,6 +111,12 @@ class ActorCore(object): | |||||
| print e | print e | ||||
| return False | return False | ||||
| def toggle(self, id): | |||||
| if self.cbpi.cache.get("actors").get(id).state == 0: | |||||
| self.on(id) | |||||
| else: | |||||
| self.off(id) | |||||
| def power(self, id, power): | def power(self, id, power): | ||||
| try: | try: | ||||
| actor = self.cbpi.cache["actors"].get(int(id)) | actor = self.cbpi.cache["actors"].get(int(id)) | ||||
| @@ -121,6 +129,20 @@ class ActorCore(object): | |||||
| print e | print e | ||||
| return False | return False | ||||
| def action(self, id, method): | |||||
| self.cbpi.cache.get("actors").get(id).instance.__getattribute__(method)() | |||||
| def toggle_timeout(self, id, seconds): | |||||
| def toggle( id, seconds): | |||||
| self.cbpi.cache.get("actors").get(int(id)).timer = int(time.time()) + int(seconds) | |||||
| self.toggle(int(id)) | |||||
| self.cbpi.sleep(seconds) | |||||
| self.cbpi.cache.get("actors").get(int(id)).timer = None | |||||
| self.toggle(int(id)) | |||||
| job = self.cbpi._socketio.start_background_task(target=toggle, id=id, seconds=seconds) | |||||
| def get_state(self, actor_id): | def get_state(self, actor_id): | ||||
| print actor_id | print actor_id | ||||
| print self.cbpi | print self.cbpi | ||||
| @@ -183,6 +205,10 @@ class SensorCore(object): | |||||
| with open(filename, "a") as file: | with open(filename, "a") as file: | ||||
| file.write(msg) | file.write(msg) | ||||
| def action(self, id, method): | |||||
| self.cbpi.cache.get("sensors").get(id).instance.__getattribute__(method)() | |||||
| class BrewingCore(object): | class BrewingCore(object): | ||||
| def __init__(self, cbpi): | def __init__(self, cbpi): | ||||
| @@ -207,6 +233,32 @@ class BrewingCore(object): | |||||
| self.cbpi.emit("SET_KETTLE_TARGET_TEMP", id=id, temp=temp) | self.cbpi.emit("SET_KETTLE_TARGET_TEMP", id=id, temp=temp) | ||||
| def toggle_automatic(self, id): | |||||
| kettle = self.cbpi.cache.get("kettle")[id] | |||||
| if kettle.state is False: | |||||
| # Start controller | |||||
| if kettle.logic is not None: | |||||
| cfg = kettle.config.copy() | |||||
| cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor)) | |||||
| instance = self.get_controller(kettle.logic).get("class")(**cfg) | |||||
| instance.init() | |||||
| kettle.instance = instance | |||||
| def run(instance): | |||||
| instance.run() | |||||
| t = self.cbpi._socketio.start_background_task(target=run, instance=instance) | |||||
| kettle.state = not kettle.state | |||||
| self.cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | |||||
| self.cbpi.emit("KETTLE_CONTROLLER_STARTED", id=id) | |||||
| else: | |||||
| # Stop controller | |||||
| kettle.instance.stop() | |||||
| kettle.state = not kettle.state | |||||
| self.cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | |||||
| self.cbpi.emit("KETTLE_CONTROLLER_STOPPED", id=id) | |||||
| class FermentationCore(object): | class FermentationCore(object): | ||||
| def __init__(self, cbpi): | def __init__(self, cbpi): | ||||
| self.cbpi = cbpi | self.cbpi = cbpi | ||||
| @@ -313,7 +365,7 @@ class CraftBeerPI(object): | |||||
| return cfg.value | return cfg.value | ||||
| def emit(self, key, **kwargs): | def emit(self, key, **kwargs): | ||||
| print key, kwargs | |||||
| if self.eventbus.get(key) is not None: | if self.eventbus.get(key) is not None: | ||||
| for value in self.eventbus[key]: | for value in self.eventbus[key]: | ||||
| if value["async"] is False: | if value["async"] is False: | ||||
| @@ -0,0 +1,44 @@ | |||||
| import sqlite3 | |||||
| import os | |||||
| from modules.core.core import cbpi | |||||
| from modules.core.db import get_db | |||||
| def execute_file(curernt_version, data): | |||||
| if curernt_version >= data["version"]: | |||||
| cbpi._app.logger.info("SKIP DB FILE: %s" % data["file"]) | |||||
| return | |||||
| try: | |||||
| with sqlite3.connect("craftbeerpi.db") as conn: | |||||
| with open('./update/%s' % data["file"], 'r') as f: | |||||
| d = f.read() | |||||
| sqlCommands = d.split(";") | |||||
| cur = conn.cursor() | |||||
| for s in sqlCommands: | |||||
| cur.execute(s) | |||||
| cur.execute("INSERT INTO schema_info (version,filename) values (?,?)", (data["version"], data["file"])) | |||||
| conn.commit() | |||||
| except sqlite3.OperationalError as err: | |||||
| print "EXCEPT" | |||||
| print err | |||||
| @cbpi.addon.core.initializer(order=-9999) | |||||
| def init(cbpi): | |||||
| with cbpi._app.app_context(): | |||||
| conn = get_db() | |||||
| cur = conn.cursor() | |||||
| current_version = None | |||||
| try: | |||||
| cur.execute("SELECT max(version) as m FROM schema_info") | |||||
| m = cur.fetchone() | |||||
| current_version = m["m"] | |||||
| except: | |||||
| pass | |||||
| result = [] | |||||
| for filename in os.listdir("./update"): | |||||
| print filename | |||||
| if filename.endswith(".sql"): | |||||
| d = {"version": int(filename[:filename.index('_')]), "file": filename} | |||||
| result.append(d) | |||||
| execute_file(current_version, d) | |||||
| @@ -1,36 +0,0 @@ | |||||
| import flask_login | |||||
| from modules.core.core import cbpi, addon | |||||
| class User(flask_login.UserMixin): | |||||
| pass | |||||
| @addon.core.initializer(order=0) | |||||
| def log(cbpi): | |||||
| cbpi._login_manager = flask_login.LoginManager() | |||||
| cbpi._login_manager.init_app(cbpi._app) | |||||
| @cbpi._app.route('/login', methods=['GET', 'POST']) | |||||
| def login(): | |||||
| user = User() | |||||
| user.id = "manuel" | |||||
| flask_login.login_user(user) | |||||
| return "OK" | |||||
| @cbpi._app.route('/logout') | |||||
| def logout(): | |||||
| flask_login.logout_user() | |||||
| return 'Logged out' | |||||
| @cbpi._login_manager.user_loader | |||||
| def user_loader(email): | |||||
| if email not in cbpi.cache["users"]: | |||||
| return | |||||
| user = User() | |||||
| user.id = email | |||||
| return user | |||||
| @cbpi._login_manager.unauthorized_handler | |||||
| def unauthorized_handler(): | |||||
| return 'Unauthorized :-(' | |||||
| @@ -214,39 +214,9 @@ class KettleView(BaseView): | |||||
| description: User created | description: User created | ||||
| """ | """ | ||||
| kettle = cbpi.cache.get("kettle")[id] | |||||
| if kettle.state is False: | |||||
| # Start controller | |||||
| if kettle.logic is not None: | |||||
| cfg = kettle.config.copy() | |||||
| cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor)) | |||||
| instance = cbpi.brewing.get_controller(kettle.logic).get("class")(**cfg) | |||||
| instance.init() | |||||
| kettle.instance = instance | |||||
| def run(instance): | |||||
| instance.run() | |||||
| t = self.api._socketio.start_background_task(target=run, instance=instance) | |||||
| kettle.state = not kettle.state | |||||
| cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | |||||
| cbpi.emit("KETTLE_CONTROLLER_STARTED", id=id) | |||||
| else: | |||||
| # Stop controller | |||||
| kettle.instance.stop() | |||||
| kettle.state = not kettle.state | |||||
| cbpi.ws_emit("UPDATE_KETTLE", cbpi.cache.get("kettle").get(id)) | |||||
| cbpi.emit("KETTLE_CONTROLLER_STOPPED", id=id) | |||||
| self.api.brewing.toggle_automatic(id) | |||||
| return ('', 204) | return ('', 204) | ||||
| #@cbpi.event("SET_TARGET_TEMP") | |||||
| def set_target_temp(id, temp): | |||||
| ''' | |||||
| Change Taget Temp Event | |||||
| :param id: kettle id | |||||
| :param temp: target temp to set | |||||
| :return: None | |||||
| ''' | |||||
| KettleView().postTargetTemp(id, temp) | |||||
| @cbpi.addon.core.backgroundjob(key="read_target_temps", interval=5) | @cbpi.addon.core.backgroundjob(key="read_target_temps", interval=5) | ||||
| def read_target_temps(api): | def read_target_temps(api): | ||||
| """ | """ | ||||
| @@ -0,0 +1,57 @@ | |||||
| import flask_login | |||||
| from flask import request | |||||
| from modules.core.core import cbpi, addon | |||||
| class User(flask_login.UserMixin): | |||||
| pass | |||||
| @addon.core.initializer(order=0) | |||||
| def log(cbpi): | |||||
| cbpi._login_manager = flask_login.LoginManager() | |||||
| cbpi._login_manager.init_app(cbpi._app) | |||||
| @cbpi._app.route('/login', methods=['POST']) | |||||
| def login(): | |||||
| data = request.json | |||||
| password = cbpi.get_config_parameter("password", None) | |||||
| if password is None: | |||||
| return ('',500) | |||||
| if password == data.get("password",""): | |||||
| user = User() | |||||
| user.id = "craftbeerpi" | |||||
| flask_login.login_user(user) | |||||
| return ('',204) | |||||
| else: | |||||
| return ('',401) | |||||
| @cbpi._app.route('/logout', methods=['POST']) | |||||
| def logout(): | |||||
| flask_login.logout_user() | |||||
| return 'Logged out' | |||||
| @cbpi._login_manager.user_loader | |||||
| def user_loader(user): | |||||
| print cbpi.get_config_parameter("password_security", "NO") | |||||
| print user | |||||
| if cbpi.get_config_parameter("password_security", "NO") == "YES": | |||||
| if user != "craftbeerpi": | |||||
| return | |||||
| user = User() | |||||
| user.id = user | |||||
| return user | |||||
| else: | |||||
| user = User() | |||||
| user.id = user | |||||
| return user | |||||
| @cbpi._login_manager.unauthorized_handler | |||||
| def unauthorized_handler(): | |||||
| return ('Please login',401) | |||||
| @@ -34,7 +34,7 @@ class SensorView(BaseView): | |||||
| 200: | 200: | ||||
| description: Sensor Action called | description: Sensor Action called | ||||
| """ | """ | ||||
| cbpi.cache.get("sensors").get(id).instance.__getattribute__(method)() | |||||
| cbpi.sensor.action(id, method) | |||||
| return ('', 204) | return ('', 204) | ||||
| def _post_post_callback(self, m): | def _post_post_callback(self, m): | ||||
| @@ -1,6 +1,7 @@ | |||||
| import yaml | import yaml | ||||
| from flask import json, url_for, Response | from flask import json, url_for, Response | ||||
| from flask_classy import FlaskView, route | from flask_classy import FlaskView, route | ||||
| from flask_login import login_required, current_user | |||||
| from git import Repo, Git | from git import Repo, Git | ||||
| from modules.core.core import cbpi | from modules.core.core import cbpi | ||||
| import pprint | import pprint | ||||
| @@ -13,6 +14,7 @@ class SystemView(FlaskView): | |||||
| from subprocess import call | from subprocess import call | ||||
| call("halt") | call("halt") | ||||
| @login_required | |||||
| @route('/shutdown', methods=['POST']) | @route('/shutdown', methods=['POST']) | ||||
| def shutdown(self): | def shutdown(self): | ||||
| """ | """ | ||||
| @@ -33,6 +35,7 @@ class SystemView(FlaskView): | |||||
| from subprocess import call | from subprocess import call | ||||
| call("reboot") | call("reboot") | ||||
| @login_required | |||||
| @route('/reboot', methods=['POST']) | @route('/reboot', methods=['POST']) | ||||
| def reboot(self): | def reboot(self): | ||||
| """ | """ | ||||
| @@ -47,6 +50,7 @@ class SystemView(FlaskView): | |||||
| self.doReboot() | self.doReboot() | ||||
| return ('', 204) | return ('', 204) | ||||
| @login_required | |||||
| @route('/tags/<name>', methods=['GET']) | @route('/tags/<name>', methods=['GET']) | ||||
| def checkout_tag(self,name): | def checkout_tag(self,name): | ||||
| repo = Repo('./') | repo = Repo('./') | ||||
| @@ -58,6 +62,7 @@ class SystemView(FlaskView): | |||||
| cbpi.notify("Checkout successful", "Please restart the system") | cbpi.notify("Checkout successful", "Please restart the system") | ||||
| return ('', 204) | return ('', 204) | ||||
| @login_required | |||||
| @route('/git/status', methods=['GET']) | @route('/git/status', methods=['GET']) | ||||
| def git_status(self): | def git_status(self): | ||||
| """ | """ | ||||
| @@ -92,6 +97,7 @@ class SystemView(FlaskView): | |||||
| return json.dumps({"tags": tags, "headcommit": str(repo.head.commit), "branchname": branch_name, | return json.dumps({"tags": tags, "headcommit": str(repo.head.commit), "branchname": branch_name, | ||||
| "master": {"changes": changes}}) | "master": {"changes": changes}}) | ||||
| @login_required | |||||
| @route('/check_update', methods=['GET']) | @route('/check_update', methods=['GET']) | ||||
| def check_update(self): | def check_update(self): | ||||
| """ | """ | ||||
| @@ -114,6 +120,7 @@ class SystemView(FlaskView): | |||||
| return json.dumps(changes) | return json.dumps(changes) | ||||
| @login_required | |||||
| @route('/git/pull', methods=['POST']) | @route('/git/pull', methods=['POST']) | ||||
| def update(self): | def update(self): | ||||
| """ | """ | ||||
| @@ -131,6 +138,24 @@ class SystemView(FlaskView): | |||||
| cbpi.notify("Pull successful", "The lasted updated was downloaded. Please restart the system") | cbpi.notify("Pull successful", "The lasted updated was downloaded. Please restart the system") | ||||
| return ('', 204) | return ('', 204) | ||||
| @route('/connect', methods=['GET']) | |||||
| def connect(self): | |||||
| """ | |||||
| Connect | |||||
| --- | |||||
| tags: | |||||
| - system | |||||
| responses: | |||||
| 200: | |||||
| description: CraftBeerPi System Cache | |||||
| """ | |||||
| if self.api.get_config_parameter("setup", "YES") == "YES": | |||||
| return json.dumps(dict(setup=True, loggedin= current_user.is_authenticated )) | |||||
| else: | |||||
| return json.dumps(dict(setup=False, loggedin= current_user.is_authenticated)) | |||||
| @login_required | |||||
| @route('/dump', methods=['GET']) | @route('/dump', methods=['GET']) | ||||
| def dump(self): | def dump(self): | ||||
| """ | """ | ||||
| @@ -1,4 +1,4 @@ | |||||
| from flask import Blueprint | |||||
| from flask import Blueprint,render_template | |||||
| from modules.core.core import cbpi | from modules.core.core import cbpi | ||||
| @@ -11,12 +11,21 @@ def init(cbpi): | |||||
| @react.route('/', methods=["GET"]) | @react.route('/', methods=["GET"]) | ||||
| def index(): | def index(): | ||||
| return react.send_static_file("index.html") | |||||
| #return react.send_static_file("index.html") | |||||
| js_files = [] | |||||
| for key, value in cbpi.cache["js"].iteritems(): | |||||
| js_files.append(value) | |||||
| print js_files | |||||
| return render_template('index.html', js_files=js_files) | |||||
| @cbpi._app.errorhandler(404) | |||||
| def page_not_found(e): | |||||
| return render_template('404.html'), 404 | |||||
| @@ -7,8 +7,7 @@ | |||||
| } | } | ||||
| .container-fluid { | .container-fluid { | ||||
| padding-right: 5px; | |||||
| padding-left: 5px; | |||||
| } | } | ||||
| @@ -1,5 +1,3 @@ | |||||
| body { | body { | ||||
| margin: 0; | |||||
| padding: 0; | |||||
| font-family: sans-serif; | |||||
| } | } | ||||
| @@ -0,0 +1,29 @@ | |||||
| <!doctype html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <meta charset="utf-8"> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
| <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> | |||||
| <link rel="stylesheet" href="/ui/static/bootstrap.min.css"> | |||||
| <link rel="stylesheet" href="/ui/static/css/font-awesome.min.css"> | |||||
| <link rel="stylesheet" href="/ui/static/bootstrap.dark.css"> | |||||
| <link href="https://fonts.googleapis.com/css?family=Dosis:200,500" rel="stylesheet"> | |||||
| <style> | |||||
| body, h1, h2, h3, h4, h5, h6 { | |||||
| font-family: 'Dosis', sans-serif; | |||||
| } | |||||
| </style> | |||||
| <title>CraftBeerPi 3.1</title> | |||||
| </head> | |||||
| <body> | |||||
| <h1>CraftBeerPi - Page not Found!</h1> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,33 @@ | |||||
| <!doctype html> | |||||
| <html lang="en"> | |||||
| <head> | |||||
| <meta charset="utf-8"> | |||||
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |||||
| <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> | |||||
| <link rel="stylesheet" href="static/bootstrap.min.css"> | |||||
| <link rel="stylesheet" href="static/css/font-awesome.min.css"> | |||||
| <link rel="stylesheet" href="static/bootstrap.dark.css"> | |||||
| <link href="https://fonts.googleapis.com/css?family=Dosis:200,500" rel="stylesheet"> | |||||
| <style> | |||||
| body, h1, h2, h3, h4, h5, h6 { | |||||
| font-family: 'Dosis', sans-serif; | |||||
| } | |||||
| </style> | |||||
| <title>CraftBeerPi 3.1</title> | |||||
| </head> | |||||
| <body> | |||||
| <div id="root" ></div> | |||||
| {% for file in js_files %} | |||||
| <script src="{{ file }}" type="text/javascript"></script> | |||||
| {% endfor %} | |||||
| <script src="static/bundle.js" type="text/javascript"></script> | |||||
| </body> | |||||
| </html> | |||||
| @@ -6,9 +6,11 @@ cbpi = CraftBeerPI() | |||||
| addon = cbpi.addon | addon = cbpi.addon | ||||
| from modules.core.db_migrate import * | |||||
| from modules.buzzer import * | from modules.buzzer import * | ||||
| from modules.config import * | from modules.config import * | ||||
| from modules.core.login import * | |||||
| from modules.login import * | |||||
| from modules.system import * | from modules.system import * | ||||
| from modules.ui import * | from modules.ui import * | ||||
| from modules.step import * | from modules.step import * | ||||
| @@ -0,0 +1 @@ | |||||
| INSERT OR IGNORE INTO config VALUES ('password', 'beer', 'text', 'LoginPassword', NULL ); | |||||